From 3de2830681adc8a3687bf77aff8185406ed64132 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Nov 2022 17:05:58 +0000 Subject: [PATCH 001/138] ci: bump softprops/action-gh-release from 0.1.14 to 0.1.15 Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 0.1.14 to 0.1.15. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/v0.1.14...v0.1.15) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/prepare_release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prepare_release.yaml b/.github/workflows/prepare_release.yaml index e3039f551..22c743258 100644 --- a/.github/workflows/prepare_release.yaml +++ b/.github/workflows/prepare_release.yaml @@ -152,7 +152,7 @@ jobs: # Create a new release - name: Create release id: create_release - uses: softprops/action-gh-release@v0.1.14 + uses: softprops/action-gh-release@v0.1.15 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 49da973372b214e95df303f78b3e7ec99fe86321 Mon Sep 17 00:00:00 2001 From: neilh20 Date: Wed, 30 Nov 2022 16:10:12 -0800 Subject: [PATCH 002/138] variablebase_debug error when using cc-arm --- src/VariableBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VariableBase.cpp b/src/VariableBase.cpp index 16cc3f10f..f330bf234 100644 --- a/src/VariableBase.cpp +++ b/src/VariableBase.cpp @@ -228,7 +228,7 @@ bool Variable::checkUUIDFormat(void) { int first_invalid = strspn(_uuid, acceptableChars); if (first_invalid != 36) { MS_DBG(F("UUID for"), getVarCode(), '(', _uuid, ')', - F("has a bad character"), _uuid[i], F("at"), first_invalid); + F("has a bad character"), _uuid[first_invalid], F("at"), first_invalid); return false; } return true; From 480e6ad952fcd6e3065e22f74a8d3e6dcbeb41fb Mon Sep 17 00:00:00 2001 From: neilh20 Date: Wed, 30 Nov 2022 16:55:47 -0800 Subject: [PATCH 003/138] Error when using cc-arm. Changed include for local search. Tested by building against examples\logging_to_MMW\logging_to_MMW.ino --- src/publishers/ThingSpeakPublisher.h | 2 +- src/sensors/AOSongDHT.h | 2 +- src/sensors/YosemitechParent.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/publishers/ThingSpeakPublisher.h b/src/publishers/ThingSpeakPublisher.h index fcb215bf7..2b0bbe89d 100644 --- a/src/publishers/ThingSpeakPublisher.h +++ b/src/publishers/ThingSpeakPublisher.h @@ -37,7 +37,7 @@ #include "ModSensorDebugger.h" #undef MS_DEBUGGING_STD #include "dataPublisherBase.h" -#include +#include "PubSubClient.h" // ============================================================================ diff --git a/src/sensors/AOSongDHT.h b/src/sensors/AOSongDHT.h index d376b699b..eb206e3cf 100644 --- a/src/sensors/AOSongDHT.h +++ b/src/sensors/AOSongDHT.h @@ -71,7 +71,7 @@ #undef MS_DEBUGGING_STD #include "VariableBase.h" #include "SensorBase.h" -#include +#include "DHT.h" #ifdef DHT11 // In older versions of the DHT library, defines were used diff --git a/src/sensors/YosemitechParent.h b/src/sensors/YosemitechParent.h index dcc2b0811..b3fa4bcbe 100644 --- a/src/sensors/YosemitechParent.h +++ b/src/sensors/YosemitechParent.h @@ -131,7 +131,7 @@ #undef MS_DEBUGGING_DEEP #include "VariableBase.h" #include "SensorBase.h" -#include +#include "YosemitechModbus.h" /* clang-format off */ /** From b1b5cc9df4363b48242eecb19fac762f2f970869 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Jan 2023 17:01:09 +0000 Subject: [PATCH 004/138] ci: bump peaceiris/actions-gh-pages from 3.9.0 to 3.9.2 Bumps [peaceiris/actions-gh-pages](https://github.com/peaceiris/actions-gh-pages) from 3.9.0 to 3.9.2. - [Release notes](https://github.com/peaceiris/actions-gh-pages/releases) - [Changelog](https://github.com/peaceiris/actions-gh-pages/blob/main/CHANGELOG.md) - [Commits](https://github.com/peaceiris/actions-gh-pages/compare/v3.9.0...v3.9.2) --- updated-dependencies: - dependency-name: peaceiris/actions-gh-pages dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/build_documentation.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_documentation.yaml b/.github/workflows/build_documentation.yaml index 74ef52723..6a47801e7 100644 --- a/.github/workflows/build_documentation.yaml +++ b/.github/workflows/build_documentation.yaml @@ -111,7 +111,7 @@ jobs: - name: Deploy to github pages if: "(github.event_name == 'release' && github.event.action == 'published') || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true')" - uses: peaceiris/actions-gh-pages@v3.9.0 + uses: peaceiris/actions-gh-pages@v3.9.2 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ${{ github.workspace }}/code_docs/ModularSensorsDoxygen/m.css From 58f64fbe4b09dc17a32a5abd3f8fc8df10e504f6 Mon Sep 17 00:00:00 2001 From: Shannon Hicks Date: Mon, 27 Feb 2023 14:04:52 -0500 Subject: [PATCH 005/138] Update CampbellClariVUE10.h --- src/sensors/CampbellClariVUE10.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sensors/CampbellClariVUE10.h b/src/sensors/CampbellClariVUE10.h index 102392d8d..0b3bbb3c4 100644 --- a/src/sensors/CampbellClariVUE10.h +++ b/src/sensors/CampbellClariVUE10.h @@ -85,7 +85,7 @@ * This is longer than the expected 250ms for a SDI-12 sensor, but I couldn't * get a response from the sensor faster than that. */ -#define CLARIVUE10_WARM_UP_TIME_MS 5500 +#define CLARIVUE10_WARM_UP_TIME_MS 8000 /// @brief Sensor::_stabilizationTime_ms; the ClariVUE10 is stable as soon as it /// warms up (0ms stabilization). #define CLARIVUE10_STABILIZATION_TIME_MS 0 @@ -96,7 +96,7 @@ * Spec sheet says the measurement time is 9s. When taking a standard * measurement I was not getting a result until after about 9335ms. */ -#define CLARIVUE10_MEASUREMENT_TIME_MS 9500 +#define CLARIVUE10_MEASUREMENT_TIME_MS 11000 /// @brief Extra wake time required for an SDI-12 sensor between the "break" /// and the time the command is sent. The ClariVUE requires no extra time. #define CLARIVUE10_EXTRA_WAKE_TIME_MS 0 From 7061e000803b79b4ca750de8a18a81ee76e8d79f Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 10 Mar 2023 13:11:08 -0500 Subject: [PATCH 006/138] Update actions Signed-off-by: Sara Damiano --- .../workflows/build_examples_platformio.yaml | 4 +- .github/workflows/build_menu.yaml | 4 +- .github/workflows/prepare_release.yaml | 4 +- continuous_integration/dependencies.json | 6 +- .../install-deps-platformio.sh | 60 +++++++++---------- library.json | 6 +- 6 files changed, 42 insertions(+), 42 deletions(-) diff --git a/.github/workflows/build_examples_platformio.yaml b/.github/workflows/build_examples_platformio.yaml index e95926898..46fa278a2 100644 --- a/.github/workflows/build_examples_platformio.yaml +++ b/.github/workflows/build_examples_platformio.yaml @@ -76,8 +76,8 @@ jobs: # Force install to get the right version - name: Install the testing version of Modular Sensors for PlatformIO run: | - pio lib -g install -f ${{ env.LIBRARY_INSTALL_SOURCE }} - pio lib show EnviroDIY_ModularSensors + pio pkg install -g -l -f ${{ env.LIBRARY_INSTALL_SOURCE }} + pio pkg show envirodiy/EnviroDIY_ModularSensors - name: Run PlatformIO env: diff --git a/.github/workflows/build_menu.yaml b/.github/workflows/build_menu.yaml index 002b7f657..e168f058c 100644 --- a/.github/workflows/build_menu.yaml +++ b/.github/workflows/build_menu.yaml @@ -274,8 +274,8 @@ jobs: # Force install to get the right version - name: Install the testing version of Modular Sensors for PlatformIO run: | - pio lib -g install -f ${{ env.LIBRARY_INSTALL_SOURCE }} - pio lib show EnviroDIY_ModularSensors + pio pkg install -g -l -f ${{ env.LIBRARY_INSTALL_SOURCE }} + pio pkg show envirodiy/EnviroDIY_ModularSensors - name: Modify menu for matrix configuration env: diff --git a/.github/workflows/prepare_release.yaml b/.github/workflows/prepare_release.yaml index e3039f551..00bdf92e0 100644 --- a/.github/workflows/prepare_release.yaml +++ b/.github/workflows/prepare_release.yaml @@ -47,8 +47,8 @@ jobs: - name: Install ModularSensors from the master branch run: | - pio lib -g install -f https://github.com/EnviroDIY/ModularSensors - pio lib show EnviroDIY_ModularSensors + pio pkg install -g -l -f https://github.com/EnviroDIY/ModularSensors + pio pkg show envirodiy/EnviroDIY_ModularSensors # Uninstall graphics libraries from Adafruit - name: Uninstall Adafruit GFX Library library diff --git a/continuous_integration/dependencies.json b/continuous_integration/dependencies.json index 46112fcd0..2dd570954 100644 --- a/continuous_integration/dependencies.json +++ b/continuous_integration/dependencies.json @@ -79,7 +79,7 @@ "owner": "adafruit", "library id": "31", "url": "https://github.com/adafruit/Adafruit_Sensor", - "version": "~1.1.5", + "version": "~1.1.9", "note": "Adafruit's unified sensor library is used by their other libraries", "authors": ["Adafruit"], "frameworks": "arduino", @@ -143,7 +143,7 @@ "owner": "adafruit", "library id": "160", "url": "https://github.com/adafruit/Adafruit_INA219", - "version": "~1.2.0", + "version": "~1.2.1", "note": "This is a library for the Adafruit INA219 high side DC current sensor boards", "authors": ["Adafruit"], "frameworks": "arduino", @@ -164,7 +164,7 @@ "owner": "adafruit", "library id": "11710", "url": "https://github.com/adafruit/Adafruit_SHT4X", - "version": "~1.0.0", + "version": "~1.0.2", "note": "Sensirion SHT4x Library by Adafruit", "authors": ["Adafruit"], "frameworks": "arduino" diff --git a/continuous_integration/install-deps-platformio.sh b/continuous_integration/install-deps-platformio.sh index 0d87046d6..e4ec51f78 100644 --- a/continuous_integration/install-deps-platformio.sh +++ b/continuous_integration/install-deps-platformio.sh @@ -4,92 +4,92 @@ set -e echo "\e[32mInstalling envirodiy/EnviroDIY_DS3231\e[0m" -pio lib -g install envirodiy/EnviroDIY_DS3231 +pio pkg install -g -l envirodiy/EnviroDIY_DS3231 echo "\e[32mInstalling arduino-libraries/RTCZero\e[0m" -pio lib -g install arduino-libraries/RTCZero +pio pkg install -g -l arduino-libraries/RTCZero echo "\e[32mInstalling greygnome/EnableInterrupt\e[0m" -pio lib -g install greygnome/EnableInterrupt +pio pkg install -g -l greygnome/EnableInterrupt echo "\e[32mInstalling greiman/SdFat\e[0m" -pio lib -g install greiman/SdFat +pio pkg install -g -l greiman/SdFat echo "\e[32mInstalling vshymanskyy/TinyGSM\e[0m" -pio lib -g install vshymanskyy/TinyGSM +pio pkg install -g -l vshymanskyy/TinyGSM echo "\e[32mInstalling knolleary/PubSubClient\e[0m" -pio lib -g install knolleary/PubSubClient +pio pkg install -g -l knolleary/PubSubClient echo "\e[32mInstalling adafruit/'Adafruit BusIO'\e[0m" -pio lib -g install adafruit/'Adafruit BusIO' +pio pkg install -g -l adafruit/'Adafruit BusIO' echo "\e[32mInstalling adafruit/'Adafruit Unified Sensor'\e[0m" -pio lib -g install adafruit/'Adafruit Unified Sensor' +pio pkg install -g -l adafruit/'Adafruit Unified Sensor' echo "\e[32mInstalling https://github.com/soligen2010/Adafruit_ADS1X15.git\e[0m" -pio lib -g install https://github.com/soligen2010/Adafruit_ADS1X15.git +pio pkg install -g -l https://github.com/soligen2010/Adafruit_ADS1X15.git echo "\e[32mInstalling adafruit/'Adafruit AM2315'\e[0m" -pio lib -g install adafruit/'Adafruit AM2315' +pio pkg install -g -l adafruit/'Adafruit AM2315' echo "\e[32mInstalling adafruit/'Adafruit BME280 Library'\e[0m" -pio lib -g install adafruit/'Adafruit BME280 Library' +pio pkg install -g -l adafruit/'Adafruit BME280 Library' echo "\e[32mInstalling adafruit/'DHT sensor library'\e[0m" -pio lib -g install adafruit/'DHT sensor library' +pio pkg install -g -l adafruit/'DHT sensor library' echo "\e[32mInstalling adafruit/'Adafruit INA219'\e[0m" -pio lib -g install adafruit/'Adafruit INA219' +pio pkg install -g -l adafruit/'Adafruit INA219' echo "\e[32mInstalling adafruit/'Adafruit MPL115A2'\e[0m" -pio lib -g install adafruit/'Adafruit MPL115A2' +pio pkg install -g -l adafruit/'Adafruit MPL115A2' echo "\e[32mInstalling adafruit/'Adafruit SHT'\e[0m" -pio lib -g install adafruit/'Adafruit SHT4x Library' +pio pkg install -g -l adafruit/'Adafruit SHT4x Library' echo "\e[32mInstalling Martin Lindupp's BMP388 Library\e[0m" -pio lib -g install https://github.com/MartinL1/BMP388_DEV.git +pio pkg install -g -l https://github.com/MartinL1/BMP388_DEV.git echo "\e[32mInstalling paulstoffregen/OneWire\e[0m" -pio lib -g install paulstoffregen/OneWire +pio pkg install -g -l paulstoffregen/OneWire echo "\e[32mInstalling milesburton/DallasTemperature\e[0m" -pio lib -g install milesburton/DallasTemperature +pio pkg install -g -l milesburton/DallasTemperature echo "\e[32mInstalling envirodiy/SDI-12\e[0m" -pio lib -g install envirodiy/SDI-12 +pio pkg install -g -l envirodiy/SDI-12 echo "\e[32mInstalling northernwidget/MS5803\e[0m" -pio lib -g install northernwidget/MS5803 +pio pkg install -g -l northernwidget/MS5803 echo "\e[32mInstalling https://github.com/EnviroDIY/Tally_Library.git#Dev_I2C\e[0m" -pio lib -g install https://github.com/EnviroDIY/Tally_Library.git#Dev_I2C +pio pkg install -g -l https://github.com/EnviroDIY/Tally_Library.git#Dev_I2C echo "\e[32mInstalling envirodiy/SensorModbusMaster\e[0m" -pio lib -g install envirodiy/SensorModbusMaster +pio pkg install -g -l envirodiy/SensorModbusMaster echo "\e[32mInstalling envirodiy/KellerModbus\e[0m" -pio lib -g install envirodiy/KellerModbus +pio pkg install -g -l envirodiy/KellerModbus echo "\e[32mInstalling envirodiy/YosemitechModbus\e[0m" -pio lib -g install envirodiy/YosemitechModbus +pio pkg install -g -l envirodiy/YosemitechModbus echo "\e[32mInstalling vshymanskyy/StreamDebugger\e[0m" -pio lib -g install vshymanskyy/StreamDebugger +pio pkg install -g -l vshymanskyy/StreamDebugger echo "\e[32mInstalling https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git\e[0m" -pio lib -g install https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git +pio pkg install -g -l https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git echo "\e[32mInstalling https://github.com/PaulStoffregen/AltSoftSerial.git\e[0m" -pio lib -g install https://github.com/PaulStoffregen/AltSoftSerial.git +pio pkg install -g -l https://github.com/PaulStoffregen/AltSoftSerial.git echo "\e[32mInstalling https://github.com/SRGDamia1/NeoSWSerial.git\e[0m" -pio lib -g install https://github.com/SRGDamia1/NeoSWSerial.git +pio pkg install -g -l https://github.com/SRGDamia1/NeoSWSerial.git echo "\e[32mInstalling https://github.com/Testato/SoftwareWire.git#v1.5.1\e[0m" -pio lib -g install https://github.com/Testato/SoftwareWire.git#v1.5.1 +pio pkg install -g -l https://github.com/Testato/SoftwareWire.git#v1.5.1 echo "\e[32m\nCurrently installed libraries:\e[0m" pio lib -g list -pio lib list \ No newline at end of file +pio lib list diff --git a/library.json b/library.json index 09553b1cc..139bcabd5 100644 --- a/library.json +++ b/library.json @@ -140,7 +140,7 @@ "owner": "adafruit", "library id": "31", "url": "https://github.com/adafruit/Adafruit_Sensor", - "version": "~1.1.5", + "version": "~1.1.9", "note": "Adafruit's unified sensor library is used by their other libraries", "authors": ["Adafruit"], "frameworks": "arduino", @@ -204,7 +204,7 @@ "owner": "adafruit", "library id": "160", "url": "https://github.com/adafruit/Adafruit_INA219", - "version": "~1.2.0", + "version": "~1.2.1", "note": "This is a library for the Adafruit INA219 high side DC current sensor boards", "authors": ["Adafruit"], "frameworks": "arduino", @@ -225,7 +225,7 @@ "owner": "adafruit", "library id": "11710", "url": "https://github.com/adafruit/Adafruit_SHT4X", - "version": "~1.0.0", + "version": "~1.0.2", "note": "Sensirion SHT4x Library by Adafruit", "authors": ["Adafruit"], "frameworks": "arduino" From 0f7af8e98f1d48de0c8a857abaffa8fcc3d7c8af Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 12:18:38 -0400 Subject: [PATCH 007/138] Tweak actions, remove sodaq from A-cli Signed-off-by: Sara Damiano --- .github/workflows/build_examples_arduino_cli.yaml | 4 ---- .github/workflows/build_examples_platformio.yaml | 2 +- .github/workflows/build_menu.yaml | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_examples_arduino_cli.yaml b/.github/workflows/build_examples_arduino_cli.yaml index 18c8901db..460a292fa 100644 --- a/.github/workflows/build_examples_arduino_cli.yaml +++ b/.github/workflows/build_examples_arduino_cli.yaml @@ -38,7 +38,6 @@ jobs: 'arduino:avr:mega', 'arduino:samd:mzero_bl', 'adafruit:samd:adafruit_feather_m0', - 'SODAQ:samd:sodaq_autonomo', ] steps: @@ -98,9 +97,6 @@ jobs: if [ ${{ matrix.fqbn }} = 'adafruit:samd:adafruit_feather_m0' ]; then echo "EXTRA_BUILD_FLAGS=-DNEOSWSERIAL_EXTERNAL_PCINT -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS -DADAFRUIT_FEATHER_M0 -D__SAMD21G18A__ -DUSB_VID=0x239A -DUSB_PID=0x800B -DUSBCON -DUSB_CONFIG_POWER=100" >> $GITHUB_ENV fi - if [ ${{ matrix.fqbn }} = 'SODAQ:samd:sodaq_autonomo' ]; then - echo "EXTRA_BUILD_FLAGS=-DNEOSWSERIAL_EXTERNAL_PCINT -DVERY_LOW_POWER -D__SAMD21J18A__ -DUSB_VID=0x2341 -DUSB_PID=0x804d -DUSBCON" >> $GITHUB_ENV - fi echo "::endgroup::" - name: Compile examples using the Arduino CLI diff --git a/.github/workflows/build_examples_platformio.yaml b/.github/workflows/build_examples_platformio.yaml index 46fa278a2..37a1793be 100644 --- a/.github/workflows/build_examples_platformio.yaml +++ b/.github/workflows/build_examples_platformio.yaml @@ -76,7 +76,7 @@ jobs: # Force install to get the right version - name: Install the testing version of Modular Sensors for PlatformIO run: | - pio pkg install -g -l -f ${{ env.LIBRARY_INSTALL_SOURCE }} + pio pkg install -g -l -f "${{ env.LIBRARY_INSTALL_SOURCE }}" pio pkg show envirodiy/EnviroDIY_ModularSensors - name: Run PlatformIO diff --git a/.github/workflows/build_menu.yaml b/.github/workflows/build_menu.yaml index e168f058c..83e53508d 100644 --- a/.github/workflows/build_menu.yaml +++ b/.github/workflows/build_menu.yaml @@ -274,7 +274,7 @@ jobs: # Force install to get the right version - name: Install the testing version of Modular Sensors for PlatformIO run: | - pio pkg install -g -l -f ${{ env.LIBRARY_INSTALL_SOURCE }} + pio pkg install -g -l -f "${{ env.LIBRARY_INSTALL_SOURCE }}" pio pkg show envirodiy/EnviroDIY_ModularSensors - name: Modify menu for matrix configuration From fa7537acdda16139c6613077a050358905eb2548 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 12:26:15 -0400 Subject: [PATCH 008/138] bump doxygen Signed-off-by: Sara Damiano --- .github/workflows/build_documentation.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_documentation.yaml b/.github/workflows/build_documentation.yaml index 6a47801e7..8d08c6698 100644 --- a/.github/workflows/build_documentation.yaml +++ b/.github/workflows/build_documentation.yaml @@ -24,7 +24,7 @@ concurrency: env: REBUILD_CACHE_NUMBER: 2 PYTHON_DEPS_ARCHIVE_NUM: 2 - DOXYGEN_VERSION: Release_1_9_3 + DOXYGEN_VERSION: Release_1_9_6 TEX_VERSION: 2019 # ^^ 2019 is the latest TeX live available on apt-get and that's good enough GRAPHVIZ_VERSION: 2.43.0 From fcedc9af1e8d8803ad1c4c179bbc6ad6c7ce3db1 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 12:39:29 -0400 Subject: [PATCH 009/138] bump doxygen Signed-off-by: Sara Damiano --- .github/workflows/build_documentation.yaml | 2 +- continuous_integration/dependencies.json | 104 ++++++++++++++++----- 2 files changed, 80 insertions(+), 26 deletions(-) diff --git a/.github/workflows/build_documentation.yaml b/.github/workflows/build_documentation.yaml index 9a52ec221..f049f63ff 100644 --- a/.github/workflows/build_documentation.yaml +++ b/.github/workflows/build_documentation.yaml @@ -24,7 +24,7 @@ concurrency: env: REBUILD_CACHE_NUMBER: 2 PYTHON_DEPS_ARCHIVE_NUM: 2 - DOXYGEN_VERSION: Release_1_9_4 + DOXYGEN_VERSION: Release_1_9_6 TEX_VERSION: 2019 # ^^ 2019 is the latest TeX live available on apt-get and that's good enough GRAPHVIZ_VERSION: 2.43.0 diff --git a/continuous_integration/dependencies.json b/continuous_integration/dependencies.json index ef145100c..37ded53a7 100644 --- a/continuous_integration/dependencies.json +++ b/continuous_integration/dependencies.json @@ -1,5 +1,5 @@ { - "action_cache_version": 14, + "action_cache_version": 15, "dependencies": [ { "name": "EnviroDIY_DS3231", @@ -8,7 +8,10 @@ "url": "https://github.com/EnviroDIY/Sodaq_DS3231", "version": "~1.3.4", "note": "An Arduino library for the DS3231 RTC (Real Time Clock), based off of the Sodaq_DS3231 library.", - "authors": ["Kees Bakker", "Sara Damiano"], + "authors": [ + "Kees Bakker", + "Sara Damiano" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -19,7 +22,9 @@ "url": "https://github.com/arduino-libraries/RTCZero", "version": "~1.6.0", "note": "Functions for using the processor real time clock in SAMD21 processors", - "authors": ["Arduino"], + "authors": [ + "Arduino" + ], "frameworks": "arduino", "platforms": "atmelsam" }, @@ -30,7 +35,9 @@ "url": "https://github.com/GreyGnome/EnableInterrupt", "version": "~1.1.0", "note": "GreyGnome's EnableInterrupt - Assign an interrupt to any supported pin on all Arduinos", - "authors": ["Mike 'GreyGnome' Schwager"], + "authors": [ + "Mike 'GreyGnome' Schwager" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -41,7 +48,9 @@ "url": "https://github.com/greiman/SdFat", "version": "~2.1.2", "note": "SdFat - FAT16/FAT32 file system for SD cards.", - "authors": ["Bill Greiman"], + "authors": [ + "Bill Greiman" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -50,7 +59,10 @@ "owner": "vshymanskyy", "version": "~0.11.5", "note": "A small Arduino library for GPRS modules.", - "authors": ["Volodymyr Shymanskyy", "Sara Damiano"], + "authors": [ + "Volodymyr Shymanskyy", + "Sara Damiano" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -61,7 +73,9 @@ "url": "https://github.com/knolleary/pubsubclient", "version": "~2.8", "note": "A client library for MQTT messaging.", - "authors": ["Nick O'Leary"] + "authors": [ + "Nick O'Leary" + ] }, { "name": "Adafruit BusIO", @@ -70,7 +84,9 @@ "url": "https://github.com/adafruit/Adafruit_BusIO", "version": "~1.11.6", "note": "Adafruit BusIO, a dependency of other Adafruit libraries", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -81,7 +97,9 @@ "url": "https://github.com/adafruit/Adafruit_Sensor", "version": "~1.1.5", "note": "Adafruit's unified sensor library is used by their other libraries", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -91,7 +109,9 @@ "version_note": "=1.2.0", "version": "https://github.com/soligen2010/Adafruit_ADS1X15.git#7d67b451f739e9a63f40f2d6d139ab582258572b", "note": "Driver for TI's ADS1015: 12-bit Differential or Single-Ended ADC with PGA and Comparator. This fork removes bugs in the Adafruit original library.", - "authors_note": ["soligen2010"], + "authors_note": [ + "soligen2010" + ], "frameworks_note": "arduino", "platforms_note": "*" }, @@ -102,7 +122,9 @@ "url": "https://github.com/adafruit/Adafruit_AM2315", "version": "~2.2.1", "note": "AOSong AM2315 I2C Temp/Humidity Sensor Library by Adafruit", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -113,7 +135,9 @@ "url": "https://github.com/adafruit/Adafruit_BME280_Library", "version": "~2.2.2", "note": "Bosch BME280 Temp/Humidity/Pressure Sensor Library by Adafruit", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -123,7 +147,9 @@ "version": "https://github.com/MartinL1/BMP388_DEV.git", "version_note": "~1.0.9", "note": "An Arduino compatible, non-blocking, I2C/SPI library for the Bosch BMP388 barometer.", - "authors": ["Martin Lindupp"], + "authors": [ + "Martin Lindupp" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -134,7 +160,9 @@ "url": "https://github.com/adafruit/DHT-sensor-library", "version": "~1.4.4", "note": "AOSong DHT Sensor Library by Adafruit", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -145,7 +173,9 @@ "url": "https://github.com/adafruit/Adafruit_INA219", "version": "~1.2.0", "note": "This is a library for the Adafruit INA219 high side DC current sensor boards", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -156,7 +186,9 @@ "url": "https://github.com/adafruit/Adafruit_MPL115A2", "version": "~2.0.0", "note": "MPL115A2 Barometer Library by Adafruit", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino" }, { @@ -166,7 +198,9 @@ "url": "https://github.com/adafruit/Adafruit_SHT4X", "version": "~1.0.0", "note": "Sensirion SHT4x Library by Adafruit", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino" }, { @@ -200,7 +234,12 @@ "url": "https://github.com/milesburton/Arduino-Temperature-Control-Library", "version": "~3.9.1", "note": "DallasTemperature - Arduino Library for Dallas Temperature ICs (DS18B20, DS18S20, DS1822, DS1820)", - "authors": ["Guil Barros", "Miles Burton", "Rob Tillart", "Tim Nuewsome"], + "authors": [ + "Guil Barros", + "Miles Burton", + "Rob Tillart", + "Tim Nuewsome" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -227,14 +266,22 @@ "url": "https://github.com/NorthernWidget/MS5803", "version": "~0.1.2", "note": "General interface to MS5803-series pressure transducers", - "authors": ["Bobby Schulz", "Andrew Wickert", "Chad Sandell", "Sara Damiano"] + "authors": [ + "Bobby Schulz", + "Andrew Wickert", + "Chad Sandell", + "Sara Damiano" + ] }, { "name": "Tally_Library_I2C", "version": "https://github.com/EnviroDIY/Tally_Library.git#Dev_I2C", "version_note": "Uses `Dev_I2C` feature branch", "note": "An Arduino library for interfacing to the Project Tally Event counter from NorthernWidget.", - "authors": ["Bobby Schulz", "Anthony Aufdenkampe"], + "authors": [ + "Bobby Schulz", + "Anthony Aufdenkampe" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -245,7 +292,9 @@ "url": "https://github.com/EnviroDIY/SensorModbusMaster", "version": "~0.6.8", "note": "EnviroDIY SensorModbusMaster - Arduino library for communicating via modbus with the Arduino acting as the modbus master.", - "authors": ["Sara Damiano"], + "authors": [ + "Sara Damiano" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -256,18 +305,23 @@ "url": "https://github.com/EnviroDIY/KellerModbus", "version": "~0.2.2", "note": "Arduino library for communication with Keller pressure and water level sensors via Modbus.", - "authors": ["Anthony Aufdenkampe"] + "authors": [ + "Anthony Aufdenkampe" + ] }, { "name": "YosemitechModbus", "owner": "envirodiy", "library id": "2078", "url": "https://github.com/EnviroDIY/YosemitechModbus", - "version": "~0.3.2", + "version": "~0.4.0", "note": "Arduino library for communication with Yosemitech sensors via Modbus.", - "authors": ["Sara Damiano", "Anthony Aufdenkampe"], + "authors": [ + "Sara Damiano", + "Anthony Aufdenkampe" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" } ] -} +} \ No newline at end of file From 95dd73cb386420faa0f3d2d9c9ecb69dac8c2fc3 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 12:40:11 -0400 Subject: [PATCH 010/138] Remove Sodaq from tests Signed-off-by: Sara Damiano --- continuous_integration/generate_job_matrix.py | 1 - continuous_integration/install-deps-arduino-cli.sh | 3 --- 2 files changed, 4 deletions(-) diff --git a/continuous_integration/generate_job_matrix.py b/continuous_integration/generate_job_matrix.py index dd290e14a..74561eb40 100644 --- a/continuous_integration/generate_job_matrix.py +++ b/continuous_integration/generate_job_matrix.py @@ -72,7 +72,6 @@ "megaatmega2560": {"fqbn": "arduino:avr:mega"}, "zeroUSB": {"fqbn": "arduino:samd:mzero_bl"}, "adafruit_feather_m0": {"fqbn": "adafruit:samd:adafruit_feather_m0"}, - "sodaq_autonomo": {"fqbn": "SODAQ:samd:sodaq_autonomo"}, } diff --git a/continuous_integration/install-deps-arduino-cli.sh b/continuous_integration/install-deps-arduino-cli.sh index 9a715e921..1fb6d4667 100644 --- a/continuous_integration/install-deps-arduino-cli.sh +++ b/continuous_integration/install-deps-arduino-cli.sh @@ -25,9 +25,6 @@ arduino-cli --config-file continuous_integration/arduino_cli.yaml core install a echo "\n\e[32mInstalling the Adafruit SAMD Core\e[0m" arduino-cli --config-file continuous_integration/arduino_cli.yaml core install adafruit:samd -echo "\n\e[32mInstalling the Sodaq SAMD Core\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core install SODAQ:samd - echo "\n\e[32mUpdating the core index\e[0m" arduino-cli --config-file continuous_integration/arduino_cli.yaml core update-index From 2644274e62d8d95f9b377126c697ecec2d28f212 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 12:45:09 -0400 Subject: [PATCH 011/138] Remove sensor tests Signed-off-by: Sara Damiano --- ...emitech_test_Y700_Y4000_simple_logging.ino | 446 ------------------ .../platformio.ini | 47 -- 2 files changed, 493 deletions(-) delete mode 100644 sensor_tests/Yosemitech_test_Y700_Y4000_simple_logging/Yosemitech_test_Y700_Y4000_simple_logging.ino delete mode 100644 sensor_tests/Yosemitech_test_Y700_Y4000_simple_logging/platformio.ini diff --git a/sensor_tests/Yosemitech_test_Y700_Y4000_simple_logging/Yosemitech_test_Y700_Y4000_simple_logging.ino b/sensor_tests/Yosemitech_test_Y700_Y4000_simple_logging/Yosemitech_test_Y700_Y4000_simple_logging.ino deleted file mode 100644 index 9435b798f..000000000 --- a/sensor_tests/Yosemitech_test_Y700_Y4000_simple_logging/Yosemitech_test_Y700_Y4000_simple_logging.ino +++ /dev/null @@ -1,446 +0,0 @@ -/** ========================================================================= - * @file Yosemitech_test_Y700_Y4000_simple_logging.ino - * @brief A data logging example for the Learn EnviroDIY tutorial. - * - * @author Sara Geleskie Damiano - * @author Anthony Aufdenkampe - * @copyright (c) 2017-2021 Stroud Water Research Center (SWRC) - * and the EnviroDIY Development Team - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studios Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger - * Created with ModularSensors v0.34.0 - * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. - * ======================================================================= */ - -// ========================================================================== -// Include the libraries required for any data logger -// ========================================================================== -/** Start [includes] */ -// The Arduino library is needed for every Arduino program. -#include - -// EnableInterrupt is used by ModularSensors for external and pin change -// interrupts and must be explicitly included in the main program. -#include - -// Include the main header for ModularSensors -#include -/** End [includes] */ - - -// ========================================================================== -// Creating Additional Serial Ports -// ========================================================================== -// The modem and a number of sensors communicate over UART/TTL - often called -// "serial". "Hardware" serial ports (automatically controlled by the MCU) are -// generally the most accurate and should be configured and used for as many -// peripherals as possible. In some cases (ie, modbus communication) many -// sensors can share the same serial port. - -// Unfortunately, most AVR boards have only one or two hardware serial ports, -// so we'll set up three types of extra software serial ports to use - -// AltSoftSerial by Paul Stoffregen -// (https://github.com/PaulStoffregen/AltSoftSerial) is the most accurate -// software serial port for AVR boards. AltSoftSerial can only be used on one -// set of pins on each board so only one AltSoftSerial port can be used. Not all -// AVR boards are supported by AltSoftSerial. -/** Start [altsoftserial] */ -#include -AltSoftSerial altSoftSerial; -/** End [altsoftserial] */ - - -// ========================================================================== -// Assigning Serial Port Functionality -// ========================================================================== - -/** Start [assign_ports_sw] */ - -// Define the serial port for modbus -// Modbus (at 9600 8N1) is used by the Keller level loggers and Yosemitech -// sensors -// Since AltSoftSerial is the best software option, we use it for modbus -// If AltSoftSerial (or its pins) aren't avaiable, use NeoSWSerial -// SoftwareSerial **WILL NOT** work for modbus! -#define modbusSerial altSoftSerial // For AltSoftSerial -// #define modbusSerial neoSSerial1 // For Neo software serial -// #define modbusSerial softSerial1 // For software serial - -/** End [assign_ports_sw] */ - - -// ========================================================================== -// Data Logging Options -// ========================================================================== -/** Start [logging_options] */ -// The name of this program file -const char* sketchName = "Yosemitech_test_Y700_Y4000_simple_logging.ino"; -// Logger ID, also becomes the prefix for the name of the data file on SD card -const char* LoggerID = "Yosemitech_test_Y700_Y4000_simple_logging"; -// How frequently (in minutes) to log data -const uint8_t loggingInterval = 2; -// Your logger's timezone. -const int8_t timeZone = -5; // Eastern Standard Time -// NOTE: Daylight savings time will not be applied! Please use standard time! - -// Set the input and output pins for the logger -// NOTE: Use -1 for pins that do not apply -const int32_t serialBaud = 115200; // Baud rate for debugging -const int8_t greenLED = 8; // Pin for the green LED -const int8_t redLED = 9; // Pin for the red LED -const int8_t buttonPin = 21; // Pin for debugging mode (ie, button pin) -const int8_t wakePin = 31; // MCU interrupt/alarm pin to wake from sleep -// Mayfly 0.x D31 = A7 -// Set the wake pin to -1 if you do not want the main processor to sleep. -// In a SAMD system where you are using the built-in rtc, set wakePin to 1 -const int8_t sdCardPwrPin = -1; // MCU SD card power pin -const int8_t sdCardSSPin = 12; // SD card chip select/slave select pin -const int8_t sensorPowerPin = 22; // MCU pin controlling main sensor power + adapters -const int8_t modbusSensorPowerPin = 11; // MCU pin controlling modbus sensor power -/** End [logging_options] */ - - -// ========================================================================== -// Using the Processor as a Sensor -// ========================================================================== -/** Start [processor_stats] */ -#include - -// Create the main processor chip "sensor" - for general metadata -const char* mcuBoardVersion = "v1.1"; -ProcessorStats mcuBoard(mcuBoardVersion); - -// Create sample number, battery voltage, and free RAM variable pointers for the -// processor -Variable* mcuBoardBatt = new ProcessorStats_Battery( - &mcuBoard, "12345678-abcd-1234-ef00-1234567890ab"); -Variable* mcuBoardAvailableRAM = new ProcessorStats_FreeRam( - &mcuBoard, "12345678-abcd-1234-ef00-1234567890ab"); -Variable* mcuBoardSampNo = new ProcessorStats_SampleNumber( - &mcuBoard, "12345678-abcd-1234-ef00-1234567890ab"); -/** End [processor_stats] */ - - -// ========================================================================== -// Maxim DS3231 RTC (Real Time Clock) -// ========================================================================== -/** Start [maxim_ds3231] */ -#include - -// Create a DS3231 sensor object -MaximDS3231 ds3231(1); - -/** End [maxim_ds3231] */ - - -// ========================================================================== -// Settings for Additional Sensors -// ========================================================================== -// Additional sensors can setup here, similar to the RTC, but only if -// they have been supported with ModularSensors wrapper functions. See: -// https://github.com/EnviroDIY/ModularSensors/wiki#just-getting-started -// Syntax for the include statement and constructor function for each sensor is -// at -// https://github.com/EnviroDIY/ModularSensors/wiki#these-sensors-are-currently-supported -// or can be copied from the `menu_a_la_carte.ino` example - - - - - -// ========================================================================== -// Yosemitech Y700 Pressure Sensor -// ========================================================================== -/** Start [yosemitech_y700] */ -#include - -// NOTE: Extra hardware and software serial ports are created in the "Settings -// for Additional Serial Ports" section - -// NOTE: Use -1 for any pins that don't apply or aren't being used. -byte y700ModbusAddress = 0x01; // The modbus address of the Y700 -const int8_t y700AdapterPower = sensorPowerPin; // RS485 adapter power pin -const int8_t y700SensorPower = modbusSensorPowerPin; // Sensor power pin -const int8_t y700EnablePin = -1; // Adapter RE/DE pin -const uint8_t y700NumberReadings = 5; -// The manufacturer recommends averaging 10 readings, but we take 5 to minimize -// power consumption - -// Create a Y700 pressure sensor object -YosemitechY700 y700(y700ModbusAddress, modbusSerial, y700AdapterPower, - y700SensorPower, y700EnablePin, y700NumberReadings); - -// Create pressure and temperature variable pointers for the Y700 -Variable* y700Pres = - new YosemitechY700_Pressure(&y700, "12345678-abcd-1234-ef00-1234567890ab"); -Variable* y700Temp = - new YosemitechY700_Temp(&y700, "12345678-abcd-1234-ef00-1234567890ab"); -/** End [yosemitech_y700] */ - - -// ========================================================================== -// Yosemitech Y4000 Multiparameter Sonde (DOmgL, Turbidity, Cond, pH, Temp, -// ORP, Chlorophyll, BGA) -// ========================================================================== -/** Start [yosemitech_y4000] */ -#include - -// NOTE: Extra hardware and software serial ports are created in the "Settings -// for Additional Serial Ports" section - -// NOTE: Use -1 for any pins that don't apply or aren't being used. -byte y4000ModbusAddress = 0x05; // The modbus address of the Y4000 -const int8_t y4000AdapterPower = sensorPowerPin; // RS485 adapter power pin -const int8_t y4000SensorPower = modbusSensorPowerPin; // Sensor power pin -const int8_t y4000EnablePin = -1; // Adapter RE/DE pin -const uint8_t y4000NumberReadings = 5; -// The manufacturer recommends averaging 10 readings, but we take 5 to minimize -// power consumption - -// Create a Yosemitech Y4000 multi-parameter sensor object -YosemitechY4000 y4000(y4000ModbusAddress, modbusSerial, y4000AdapterPower, - y4000SensorPower, y4000EnablePin, y4000NumberReadings); - -// Create all of the variable pointers for the Y4000 -Variable* y4000DO = - new YosemitechY4000_DOmgL(&y4000, "12345678-abcd-1234-ef00-1234567890ab"); -Variable* y4000Turb = new YosemitechY4000_Turbidity( - &y4000, "12345678-abcd-1234-ef00-1234567890ab"); -Variable* y4000Cond = - new YosemitechY4000_Cond(&y4000, "12345678-abcd-1234-ef00-1234567890ab"); -Variable* y4000pH = - new YosemitechY4000_pH(&y4000, "12345678-abcd-1234-ef00-1234567890ab"); -Variable* y4000Temp = - new YosemitechY4000_Temp(&y4000, "12345678-abcd-1234-ef00-1234567890ab"); -Variable* y4000ORP = - new YosemitechY4000_ORP(&y4000, "12345678-abcd-1234-ef00-1234567890ab"); -Variable* y4000Chloro = new YosemitechY4000_Chlorophyll( - &y4000, "12345678-abcd-1234-ef00-1234567890ab"); -Variable* y4000BGA = - new YosemitechY4000_BGA(&y4000, "12345678-abcd-1234-ef00-1234567890ab"); -/** End [yosemitech_y4000] */ - - -// ========================================================================== -// Creating the Variable Array[s] and Filling with Variable Objects -// ========================================================================== -/** Start [variable_arrays] */ -Variable* variableList[] = { - new ProcessorStats_SampleNumber(&mcuBoard), - new ProcessorStats_FreeRam(&mcuBoard), - new ProcessorStats_Battery(&mcuBoard), - new MaximDS3231_Temp(&ds3231), - y700Pres, - y700Temp, - y4000DO, - y4000Turb, - y4000Cond, - y4000pH, - y4000Temp, - // y4000ORP, - y4000Chloro, - y4000BGA, - -}; -// Count up the number of pointers in the array -int variableCount = sizeof(variableList) / sizeof(variableList[0]); - -// Create the VariableArray object -VariableArray varArray; -/** End [variable_arrays] */ - - -// ========================================================================== -// The Logger Object[s] -// ========================================================================== -/** Start [loggers] */ -// Create a logger instance -Logger dataLogger; -/** End [loggers] */ - - -// ========================================================================== -// Working Functions -// ========================================================================== -/** Start [working_functions] */ -// Flashes the LED's on the primary board -void greenredflash(uint8_t numFlash = 4, uint8_t rate = 75) { - for (uint8_t i = 0; i < numFlash; i++) { - digitalWrite(greenLED, HIGH); - digitalWrite(redLED, LOW); - delay(rate); - digitalWrite(greenLED, LOW); - digitalWrite(redLED, HIGH); - delay(rate); - } - digitalWrite(redLED, LOW); -} - -// Uses the processor sensor object to read the battery voltage -// NOTE: This will actually return the battery level from the previous update! -float getBatteryVoltage() { - if (mcuBoard.sensorValues[0] == -9999) mcuBoard.update(); - return mcuBoard.sensorValues[0]; -} -/** End [working_functions] */ - - -// ========================================================================== -// Arduino Setup Function -// ========================================================================== -/** Start [setup] */ -void setup() { - // Start the primary serial connection - Serial.begin(serialBaud); - - // Print a start-up note to the first serial port - Serial.print(F("\n\nNow running ")); - Serial.print(sketchName); - Serial.print(F(" on Logger ")); - Serial.println(LoggerID); - Serial.println(); - - Serial.print(F("Using ModularSensors Library version ")); - Serial.println(MODULAR_SENSORS_VERSION); - - /** Start [setup_flashing_led] */ - // Set up pins for the LED's - pinMode(greenLED, OUTPUT); - digitalWrite(greenLED, LOW); - pinMode(redLED, OUTPUT); - digitalWrite(redLED, LOW); - // Blink the LEDs to show the board is on and starting up - greenredflash(); - /** End [setup_flashing_led] */ - - /** Start [setup_logger] */ - // Set the timezones for the logger/data and the RTC - // Logging in the given time zone - Logger::setLoggerTimeZone(timeZone); - // It is STRONGLY RECOMMENDED that you set the RTC to be in UTC (UTC+0) - Logger::setRTCTimeZone(0); - - // Set information pins - dataLogger.setLoggerPins(wakePin, sdCardSSPin, sdCardPwrPin, buttonPin, - greenLED); - - // Begin the variable array[s], logger[s], and publisher[s] - varArray.begin(variableCount, variableList); - dataLogger.begin(LoggerID, loggingInterval, &varArray); - - /** Start [setup_sensors] */ - - Serial.println(F("Setting up sensors...")); - varArray.setupSensors(); - /** End [setup_sensors] */ - - /** Start [setup_file] */ - // Create the log file, adding the default header to it - // Do this last so we have the best chance of getting the time correct and - // all sensor names correct - dataLogger.createLogFile(true); // true = write a new header - /** End [setup_file] */ - /** Start [setup_sleep] */ - // Call the processor sleep - Serial.println(F("Putting processor to sleep\n")); - dataLogger.systemSleep(); - /** End [setup_sleep] */ -} -/** End [setup] */ - - -// ========================================================================== -// Arduino Loop Function -// ========================================================================== -/** Start [complex_loop] */ -// Use this long loop when you want to do something special -// Because of the way alarms work on the RTC, it will wake the processor and -// start the loop every minute exactly on the minute. -// The processor may also be woken up by another interrupt or level change on a -// pin - from a button or some other input. -// The "if" statements in the loop determine what will happen - whether the -// sensors update, testing mode starts, or it goes back to sleep. -void loop() { - // Reset the watchdog - dataLogger.watchDogTimer.resetWatchDog(); - - // Assuming we were woken up by the clock, check if the current time is an - // even interval of the logging interval - // We're only doing anything at all if the battery is above 3.4V - if (dataLogger.checkInterval() && getBatteryVoltage() > 3.4) { - // Flag to notify that we're in already awake and logging a point - Logger::isLoggingNow = true; - dataLogger.watchDogTimer.resetWatchDog(); - - // Print a line to show new reading - Serial.println(F("------------------------------------------")); - // Turn on the LED to show we're taking a reading - dataLogger.alertOn(); - // Power up the SD Card, but skip any waits after power up - dataLogger.turnOnSDcard(false); - dataLogger.watchDogTimer.resetWatchDog(); - - // Start the stream for the modbus sensors, if your RS485 adapter bleeds - // current from data pins when powered off & you stop modbus serial - // connection with digitalWrite(5, LOW), below. - // https://github.com/EnviroDIY/ModularSensors/issues/140#issuecomment-389380833 - altSoftSerial.begin(9600); - - // Do a complete update on the variable array. - // This this includes powering all of the sensors, getting updated - // values, and turing them back off. - // NOTE: The wake function for each sensor should force sensor setup - // to run if the sensor was not previously set up. - varArray.completeUpdate(); - - dataLogger.watchDogTimer.resetWatchDog(); - - // Reset modbus serial pins to LOW, if your RS485 adapter bleeds power - // on sleep, because Modbus Stop bit leaves these pins HIGH. - // https://github.com/EnviroDIY/ModularSensors/issues/140#issuecomment-389380833 - digitalWrite(5, LOW); // Reset AltSoftSerial Tx pin to LOW - digitalWrite(6, LOW); // Reset AltSoftSerial Rx pin to LOW - - // Create a csv data record and save it to the log file - dataLogger.logToSD(); - dataLogger.watchDogTimer.resetWatchDog(); - - - // Cut power from the SD card - without additional housekeeping wait - dataLogger.turnOffSDcard(false); - dataLogger.watchDogTimer.resetWatchDog(); - // Turn off the LED - dataLogger.alertOff(); - // Print a line to show reading ended - Serial.println(F("------------------------------------------\n")); - - // Unset flag - Logger::isLoggingNow = false; - } - - // Check if it was instead the testing interrupt that woke us up - if (Logger::startTesting) { - // Start the stream for the modbus sensors, if your RS485 adapter bleeds - // current from data pins when powered off & you stop modbus serial - // connection with digitalWrite(5, LOW), below. - // https://github.com/EnviroDIY/ModularSensors/issues/140#issuecomment-389380833 - altSoftSerial.begin(9600); - - dataLogger.testingMode(); - } - - // Reset modbus serial pins to LOW, if your RS485 adapter bleeds power - // on sleep, because Modbus Stop bit leaves these pins HIGH. - // https://github.com/EnviroDIY/ModularSensors/issues/140#issuecomment-389380833 - digitalWrite(5, LOW); // Reset AltSoftSerial Tx pin to LOW - digitalWrite(6, LOW); // Reset AltSoftSerial Rx pin to LOW - - // Call the processor sleep - dataLogger.systemSleep(); -} -/** End [complex_loop] */ diff --git a/sensor_tests/Yosemitech_test_Y700_Y4000_simple_logging/platformio.ini b/sensor_tests/Yosemitech_test_Y700_Y4000_simple_logging/platformio.ini deleted file mode 100644 index ae7005a25..000000000 --- a/sensor_tests/Yosemitech_test_Y700_Y4000_simple_logging/platformio.ini +++ /dev/null @@ -1,47 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; http://docs.platformio.org/page/projectconf.html - -[platformio] -description = ModularSensors example logging data to an SD card from external sensors -src_dir = utilities/Yosemitech_test_6sensors_simple_logging - -[env:mayfly] -monitor_speed = 115200 -board = mayfly -platform = atmelavr -framework = arduino -lib_ldf_mode = deep+ -lib_ignore = - RTCZero - Adafruit NeoPixel - Adafruit GFX Library - Adafruit SSD1306 - Adafruit ADXL343 - Adafruit STMPE610 - Adafruit TouchScreen - Adafruit ILI9341 -build_flags = - -DSDI12_EXTERNAL_PCINT - -DNEOSWSERIAL_EXTERNAL_PCINT - -DMQTT_MAX_PACKET_SIZE=240 - -DTINY_GSM_RX_BUFFER=64 - -DTINY_GSM_YIELD_MS=2 - -DMS_YOSEMITECHPARENT_DEBUG - ; -D MS_YOSEMITECHPARENT_DEBUG_DEEP -lib_deps = - EnviroDIY_ModularSensors@=0.34.0 - -; Using ModularSensors *Y551_Y550* branch (v0.33 ish) on 12/21/2021 -; https://github.com/EnviroDIY/ModularSensors.git#e27236f22d311d43800b34dd9d064b503848dbe9 - - https://github.com/PaulStoffregen/AltSoftSerial.git - https://github.com/SRGDamia1/NeoSWSerial.git - https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git -; ^^ These are software serial port emulator libraries, you may not need them From 4766d206d65b89a1d0bbca46753df26a15592cf9 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 12:45:56 -0400 Subject: [PATCH 012/138] Add sensor tests to git ignore Signed-off-by: Sara Damiano --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f38d25314..4b2fe4792 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,4 @@ continuous_integration/arduino_cli_local.yaml compile_results.log continuous_integration_artifacts/* arduino_cli.log +**/sensor_tests/* From e30f813413241cebc4c8aaba11f9b2e08328e916 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 12:48:21 -0400 Subject: [PATCH 013/138] Remove unfound, failing dependency from A-CLI Signed-off-by: Sara Damiano --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 47b89b128..fe0a35b7b 100644 --- a/library.properties +++ b/library.properties @@ -8,4 +8,4 @@ category=Sensors url=https://github.com/EnviroDIY/ModularSensors architectures=avr,samd includes=LoggerBase.h -depends=EnviroDIY_DS3231, RTCZero, EnableInterrupt, SdFat, TinyGSM, PubSubClient, Adafruit BusIO, Adafruit Unified Sensor, Adafruit ADS1X15, Adafruit AM2315, Adafruit BME280 Library, DHT sensor library, Adafruit INA219, Adafruit MPL115A2, Adafruit SHT4x Library, OneWire, DallasTemperature, SDI-12, MS5803, SensorModbusMaster, KellerModbus, YosemitechModbus +depends=EnviroDIY_DS3231, RTCZero, EnableInterrupt, SdFat, TinyGSM, PubSubClient, Adafruit BusIO, Adafruit Unified Sensor, Adafruit ADS1X15, Adafruit AM2315, Adafruit BME280 Library, DHT sensor library, Adafruit INA219, Adafruit MPL115A2, Adafruit SHT4x Library, OneWire, DallasTemperature, SDI-12, SensorModbusMaster, KellerModbus, YosemitechModbus From d86eef8724407cf31e94ef869fa1b0ee30bdd229 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 13:08:23 -0400 Subject: [PATCH 014/138] debugging actions Signed-off-by: Sara Damiano --- .github/workflows/build_examples.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/build_examples.yaml b/.github/workflows/build_examples.yaml index e16bd4fbd..adde9ad3a 100644 --- a/.github/workflows/build_examples.yaml +++ b/.github/workflows/build_examples.yaml @@ -40,6 +40,19 @@ jobs: path: | continuous_integration_artifacts/ + print_job_matrix: + name: print_job_matrix + runs-on: ubuntu-latest + needs: generate_matrix + steps: + - name: Check the generated matrix output + run: | + echo "Arduino job matrix:" + echo "${{ needs.generate_matrix.outputs.arduino_job_matrix }}" + echo + echo "PlatformIO job matrix" + echo "${{ needs.generate_matrix.outputs.pio_job_matrix }}" + build_ex_arduino: name: ${{ matrix.job_info.job_name }} runs-on: ubuntu-latest From 7882402b1670033f019297f39f15569212700ac4 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 13:18:59 -0400 Subject: [PATCH 015/138] different attempt to set output from python Signed-off-by: Sara Damiano --- continuous_integration/generate_job_matrix.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/continuous_integration/generate_job_matrix.py b/continuous_integration/generate_job_matrix.py index 74561eb40..3c05f66a4 100644 --- a/continuous_integration/generate_job_matrix.py +++ b/continuous_integration/generate_job_matrix.py @@ -694,6 +694,13 @@ def extend_pio_config(added_envs): json_out.close() +#%% +# different attempt to save output +with open(os.environ["GITHUB_OUTPUT"], "a") as fh: + print("arduino_job_matrix={}".format(json.dumps(arduino_job_matrix)), file=fh) + print("pio_job_matrix={}".format(json.dumps(pio_job_matrix)), file=fh) + + #%% if "GITHUB_WORKSPACE" not in os.environ.keys(): try: From e426ce8af3a5ef53b1be83da56368ce4e9e8c334 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 13:23:45 -0400 Subject: [PATCH 016/138] bump some dependencies Signed-off-by: Sara Damiano --- continuous_integration/dependencies.json | 106 ++++++----------------- library.json | 6 +- 2 files changed, 29 insertions(+), 83 deletions(-) diff --git a/continuous_integration/dependencies.json b/continuous_integration/dependencies.json index 37ded53a7..d64492000 100644 --- a/continuous_integration/dependencies.json +++ b/continuous_integration/dependencies.json @@ -8,10 +8,7 @@ "url": "https://github.com/EnviroDIY/Sodaq_DS3231", "version": "~1.3.4", "note": "An Arduino library for the DS3231 RTC (Real Time Clock), based off of the Sodaq_DS3231 library.", - "authors": [ - "Kees Bakker", - "Sara Damiano" - ], + "authors": ["Kees Bakker", "Sara Damiano"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -22,9 +19,7 @@ "url": "https://github.com/arduino-libraries/RTCZero", "version": "~1.6.0", "note": "Functions for using the processor real time clock in SAMD21 processors", - "authors": [ - "Arduino" - ], + "authors": ["Arduino"], "frameworks": "arduino", "platforms": "atmelsam" }, @@ -35,9 +30,7 @@ "url": "https://github.com/GreyGnome/EnableInterrupt", "version": "~1.1.0", "note": "GreyGnome's EnableInterrupt - Assign an interrupt to any supported pin on all Arduinos", - "authors": [ - "Mike 'GreyGnome' Schwager" - ], + "authors": ["Mike 'GreyGnome' Schwager"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -48,9 +41,7 @@ "url": "https://github.com/greiman/SdFat", "version": "~2.1.2", "note": "SdFat - FAT16/FAT32 file system for SD cards.", - "authors": [ - "Bill Greiman" - ], + "authors": ["Bill Greiman"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -59,10 +50,7 @@ "owner": "vshymanskyy", "version": "~0.11.5", "note": "A small Arduino library for GPRS modules.", - "authors": [ - "Volodymyr Shymanskyy", - "Sara Damiano" - ], + "authors": ["Volodymyr Shymanskyy", "Sara Damiano"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -73,9 +61,7 @@ "url": "https://github.com/knolleary/pubsubclient", "version": "~2.8", "note": "A client library for MQTT messaging.", - "authors": [ - "Nick O'Leary" - ] + "authors": ["Nick O'Leary"] }, { "name": "Adafruit BusIO", @@ -84,9 +70,7 @@ "url": "https://github.com/adafruit/Adafruit_BusIO", "version": "~1.11.6", "note": "Adafruit BusIO, a dependency of other Adafruit libraries", - "authors": [ - "Adafruit" - ], + "authors": ["Adafruit"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -95,11 +79,9 @@ "owner": "adafruit", "library id": "31", "url": "https://github.com/adafruit/Adafruit_Sensor", - "version": "~1.1.5", + "version": "~1.1.9", "note": "Adafruit's unified sensor library is used by their other libraries", - "authors": [ - "Adafruit" - ], + "authors": ["Adafruit"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -109,9 +91,7 @@ "version_note": "=1.2.0", "version": "https://github.com/soligen2010/Adafruit_ADS1X15.git#7d67b451f739e9a63f40f2d6d139ab582258572b", "note": "Driver for TI's ADS1015: 12-bit Differential or Single-Ended ADC with PGA and Comparator. This fork removes bugs in the Adafruit original library.", - "authors_note": [ - "soligen2010" - ], + "authors_note": ["soligen2010"], "frameworks_note": "arduino", "platforms_note": "*" }, @@ -122,9 +102,7 @@ "url": "https://github.com/adafruit/Adafruit_AM2315", "version": "~2.2.1", "note": "AOSong AM2315 I2C Temp/Humidity Sensor Library by Adafruit", - "authors": [ - "Adafruit" - ], + "authors": ["Adafruit"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -135,9 +113,7 @@ "url": "https://github.com/adafruit/Adafruit_BME280_Library", "version": "~2.2.2", "note": "Bosch BME280 Temp/Humidity/Pressure Sensor Library by Adafruit", - "authors": [ - "Adafruit" - ], + "authors": ["Adafruit"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -147,9 +123,7 @@ "version": "https://github.com/MartinL1/BMP388_DEV.git", "version_note": "~1.0.9", "note": "An Arduino compatible, non-blocking, I2C/SPI library for the Bosch BMP388 barometer.", - "authors": [ - "Martin Lindupp" - ], + "authors": ["Martin Lindupp"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -160,9 +134,7 @@ "url": "https://github.com/adafruit/DHT-sensor-library", "version": "~1.4.4", "note": "AOSong DHT Sensor Library by Adafruit", - "authors": [ - "Adafruit" - ], + "authors": ["Adafruit"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -171,11 +143,9 @@ "owner": "adafruit", "library id": "160", "url": "https://github.com/adafruit/Adafruit_INA219", - "version": "~1.2.0", + "version": "~1.2.1", "note": "This is a library for the Adafruit INA219 high side DC current sensor boards", - "authors": [ - "Adafruit" - ], + "authors": ["Adafruit"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -186,9 +156,7 @@ "url": "https://github.com/adafruit/Adafruit_MPL115A2", "version": "~2.0.0", "note": "MPL115A2 Barometer Library by Adafruit", - "authors": [ - "Adafruit" - ], + "authors": ["Adafruit"], "frameworks": "arduino" }, { @@ -196,11 +164,9 @@ "owner": "adafruit", "library id": "11710", "url": "https://github.com/adafruit/Adafruit_SHT4X", - "version": "~1.0.0", + "version": "~1.0.2", "note": "Sensirion SHT4x Library by Adafruit", - "authors": [ - "Adafruit" - ], + "authors": ["Adafruit"], "frameworks": "arduino" }, { @@ -234,12 +200,7 @@ "url": "https://github.com/milesburton/Arduino-Temperature-Control-Library", "version": "~3.9.1", "note": "DallasTemperature - Arduino Library for Dallas Temperature ICs (DS18B20, DS18S20, DS1822, DS1820)", - "authors": [ - "Guil Barros", - "Miles Burton", - "Rob Tillart", - "Tim Nuewsome" - ], + "authors": ["Guil Barros", "Miles Burton", "Rob Tillart", "Tim Nuewsome"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -266,22 +227,14 @@ "url": "https://github.com/NorthernWidget/MS5803", "version": "~0.1.2", "note": "General interface to MS5803-series pressure transducers", - "authors": [ - "Bobby Schulz", - "Andrew Wickert", - "Chad Sandell", - "Sara Damiano" - ] + "authors": ["Bobby Schulz", "Andrew Wickert", "Chad Sandell", "Sara Damiano"] }, { "name": "Tally_Library_I2C", "version": "https://github.com/EnviroDIY/Tally_Library.git#Dev_I2C", "version_note": "Uses `Dev_I2C` feature branch", "note": "An Arduino library for interfacing to the Project Tally Event counter from NorthernWidget.", - "authors": [ - "Bobby Schulz", - "Anthony Aufdenkampe" - ], + "authors": ["Bobby Schulz", "Anthony Aufdenkampe"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -292,9 +245,7 @@ "url": "https://github.com/EnviroDIY/SensorModbusMaster", "version": "~0.6.8", "note": "EnviroDIY SensorModbusMaster - Arduino library for communicating via modbus with the Arduino acting as the modbus master.", - "authors": [ - "Sara Damiano" - ], + "authors": ["Sara Damiano"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -305,9 +256,7 @@ "url": "https://github.com/EnviroDIY/KellerModbus", "version": "~0.2.2", "note": "Arduino library for communication with Keller pressure and water level sensors via Modbus.", - "authors": [ - "Anthony Aufdenkampe" - ] + "authors": ["Anthony Aufdenkampe"] }, { "name": "YosemitechModbus", @@ -316,12 +265,9 @@ "url": "https://github.com/EnviroDIY/YosemitechModbus", "version": "~0.4.0", "note": "Arduino library for communication with Yosemitech sensors via Modbus.", - "authors": [ - "Sara Damiano", - "Anthony Aufdenkampe" - ], + "authors": ["Sara Damiano", "Anthony Aufdenkampe"], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" } ] -} \ No newline at end of file +} diff --git a/library.json b/library.json index 9db870639..58ec993c2 100644 --- a/library.json +++ b/library.json @@ -140,7 +140,7 @@ "owner": "adafruit", "library id": "31", "url": "https://github.com/adafruit/Adafruit_Sensor", - "version": "~1.1.5", + "version": "~1.1.9", "note": "Adafruit's unified sensor library is used by their other libraries", "authors": ["Adafruit"], "frameworks": "arduino", @@ -204,7 +204,7 @@ "owner": "adafruit", "library id": "160", "url": "https://github.com/adafruit/Adafruit_INA219", - "version": "~1.2.0", + "version": "~1.2.1", "note": "This is a library for the Adafruit INA219 high side DC current sensor boards", "authors": ["Adafruit"], "frameworks": "arduino", @@ -225,7 +225,7 @@ "owner": "adafruit", "library id": "11710", "url": "https://github.com/adafruit/Adafruit_SHT4X", - "version": "~1.0.0", + "version": "~1.0.2", "note": "Sensirion SHT4x Library by Adafruit", "authors": ["Adafruit"], "frameworks": "arduino" From 5be5dfd7679371abde1bc0f03891df7627350fab Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 13:59:12 -0400 Subject: [PATCH 017/138] Revert "bump doxygen" This reverts commit a7f4792ea49102b1ace8ee19f6401f28672c7412. --- .github/workflows/build_documentation.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_documentation.yaml b/.github/workflows/build_documentation.yaml index 8d08c6698..6a47801e7 100644 --- a/.github/workflows/build_documentation.yaml +++ b/.github/workflows/build_documentation.yaml @@ -24,7 +24,7 @@ concurrency: env: REBUILD_CACHE_NUMBER: 2 PYTHON_DEPS_ARCHIVE_NUM: 2 - DOXYGEN_VERSION: Release_1_9_6 + DOXYGEN_VERSION: Release_1_9_3 TEX_VERSION: 2019 # ^^ 2019 is the latest TeX live available on apt-get and that's good enough GRAPHVIZ_VERSION: 2.43.0 From 31fe61fed7fa33962f429cf0119a5a74196ef83f Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 13:59:35 -0400 Subject: [PATCH 018/138] Revert "Tweak actions, remove sodaq from A-cli" This reverts commit dbabe82795f78e9d8764c8f5a898e7a3467200b8. --- .github/workflows/build_examples_arduino_cli.yaml | 4 ++++ .github/workflows/build_examples_platformio.yaml | 2 +- .github/workflows/build_menu.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_examples_arduino_cli.yaml b/.github/workflows/build_examples_arduino_cli.yaml index 460a292fa..18c8901db 100644 --- a/.github/workflows/build_examples_arduino_cli.yaml +++ b/.github/workflows/build_examples_arduino_cli.yaml @@ -38,6 +38,7 @@ jobs: 'arduino:avr:mega', 'arduino:samd:mzero_bl', 'adafruit:samd:adafruit_feather_m0', + 'SODAQ:samd:sodaq_autonomo', ] steps: @@ -97,6 +98,9 @@ jobs: if [ ${{ matrix.fqbn }} = 'adafruit:samd:adafruit_feather_m0' ]; then echo "EXTRA_BUILD_FLAGS=-DNEOSWSERIAL_EXTERNAL_PCINT -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS -DADAFRUIT_FEATHER_M0 -D__SAMD21G18A__ -DUSB_VID=0x239A -DUSB_PID=0x800B -DUSBCON -DUSB_CONFIG_POWER=100" >> $GITHUB_ENV fi + if [ ${{ matrix.fqbn }} = 'SODAQ:samd:sodaq_autonomo' ]; then + echo "EXTRA_BUILD_FLAGS=-DNEOSWSERIAL_EXTERNAL_PCINT -DVERY_LOW_POWER -D__SAMD21J18A__ -DUSB_VID=0x2341 -DUSB_PID=0x804d -DUSBCON" >> $GITHUB_ENV + fi echo "::endgroup::" - name: Compile examples using the Arduino CLI diff --git a/.github/workflows/build_examples_platformio.yaml b/.github/workflows/build_examples_platformio.yaml index 37a1793be..46fa278a2 100644 --- a/.github/workflows/build_examples_platformio.yaml +++ b/.github/workflows/build_examples_platformio.yaml @@ -76,7 +76,7 @@ jobs: # Force install to get the right version - name: Install the testing version of Modular Sensors for PlatformIO run: | - pio pkg install -g -l -f "${{ env.LIBRARY_INSTALL_SOURCE }}" + pio pkg install -g -l -f ${{ env.LIBRARY_INSTALL_SOURCE }} pio pkg show envirodiy/EnviroDIY_ModularSensors - name: Run PlatformIO diff --git a/.github/workflows/build_menu.yaml b/.github/workflows/build_menu.yaml index 83e53508d..e168f058c 100644 --- a/.github/workflows/build_menu.yaml +++ b/.github/workflows/build_menu.yaml @@ -274,7 +274,7 @@ jobs: # Force install to get the right version - name: Install the testing version of Modular Sensors for PlatformIO run: | - pio pkg install -g -l -f "${{ env.LIBRARY_INSTALL_SOURCE }}" + pio pkg install -g -l -f ${{ env.LIBRARY_INSTALL_SOURCE }} pio pkg show envirodiy/EnviroDIY_ModularSensors - name: Modify menu for matrix configuration From f7fdc7ccfaf4c91200a0abc0669e7916ec9ed280 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 14 Mar 2023 13:59:54 -0400 Subject: [PATCH 019/138] Revert "Update actions" This reverts commit 2e5bdbc5a424ca49e295caca02424a3c5a7aa2d1. --- .../workflows/build_examples_platformio.yaml | 4 +- .github/workflows/build_menu.yaml | 4 +- .github/workflows/prepare_release.yaml | 4 +- continuous_integration/dependencies.json | 6 +- .../install-deps-platformio.sh | 60 +++++++++---------- library.json | 6 +- 6 files changed, 42 insertions(+), 42 deletions(-) diff --git a/.github/workflows/build_examples_platformio.yaml b/.github/workflows/build_examples_platformio.yaml index 46fa278a2..e95926898 100644 --- a/.github/workflows/build_examples_platformio.yaml +++ b/.github/workflows/build_examples_platformio.yaml @@ -76,8 +76,8 @@ jobs: # Force install to get the right version - name: Install the testing version of Modular Sensors for PlatformIO run: | - pio pkg install -g -l -f ${{ env.LIBRARY_INSTALL_SOURCE }} - pio pkg show envirodiy/EnviroDIY_ModularSensors + pio lib -g install -f ${{ env.LIBRARY_INSTALL_SOURCE }} + pio lib show EnviroDIY_ModularSensors - name: Run PlatformIO env: diff --git a/.github/workflows/build_menu.yaml b/.github/workflows/build_menu.yaml index e168f058c..002b7f657 100644 --- a/.github/workflows/build_menu.yaml +++ b/.github/workflows/build_menu.yaml @@ -274,8 +274,8 @@ jobs: # Force install to get the right version - name: Install the testing version of Modular Sensors for PlatformIO run: | - pio pkg install -g -l -f ${{ env.LIBRARY_INSTALL_SOURCE }} - pio pkg show envirodiy/EnviroDIY_ModularSensors + pio lib -g install -f ${{ env.LIBRARY_INSTALL_SOURCE }} + pio lib show EnviroDIY_ModularSensors - name: Modify menu for matrix configuration env: diff --git a/.github/workflows/prepare_release.yaml b/.github/workflows/prepare_release.yaml index b85fb6cee..22c743258 100644 --- a/.github/workflows/prepare_release.yaml +++ b/.github/workflows/prepare_release.yaml @@ -47,8 +47,8 @@ jobs: - name: Install ModularSensors from the master branch run: | - pio pkg install -g -l -f https://github.com/EnviroDIY/ModularSensors - pio pkg show envirodiy/EnviroDIY_ModularSensors + pio lib -g install -f https://github.com/EnviroDIY/ModularSensors + pio lib show EnviroDIY_ModularSensors # Uninstall graphics libraries from Adafruit - name: Uninstall Adafruit GFX Library library diff --git a/continuous_integration/dependencies.json b/continuous_integration/dependencies.json index 2dd570954..46112fcd0 100644 --- a/continuous_integration/dependencies.json +++ b/continuous_integration/dependencies.json @@ -79,7 +79,7 @@ "owner": "adafruit", "library id": "31", "url": "https://github.com/adafruit/Adafruit_Sensor", - "version": "~1.1.9", + "version": "~1.1.5", "note": "Adafruit's unified sensor library is used by their other libraries", "authors": ["Adafruit"], "frameworks": "arduino", @@ -143,7 +143,7 @@ "owner": "adafruit", "library id": "160", "url": "https://github.com/adafruit/Adafruit_INA219", - "version": "~1.2.1", + "version": "~1.2.0", "note": "This is a library for the Adafruit INA219 high side DC current sensor boards", "authors": ["Adafruit"], "frameworks": "arduino", @@ -164,7 +164,7 @@ "owner": "adafruit", "library id": "11710", "url": "https://github.com/adafruit/Adafruit_SHT4X", - "version": "~1.0.2", + "version": "~1.0.0", "note": "Sensirion SHT4x Library by Adafruit", "authors": ["Adafruit"], "frameworks": "arduino" diff --git a/continuous_integration/install-deps-platformio.sh b/continuous_integration/install-deps-platformio.sh index e4ec51f78..0d87046d6 100644 --- a/continuous_integration/install-deps-platformio.sh +++ b/continuous_integration/install-deps-platformio.sh @@ -4,92 +4,92 @@ set -e echo "\e[32mInstalling envirodiy/EnviroDIY_DS3231\e[0m" -pio pkg install -g -l envirodiy/EnviroDIY_DS3231 +pio lib -g install envirodiy/EnviroDIY_DS3231 echo "\e[32mInstalling arduino-libraries/RTCZero\e[0m" -pio pkg install -g -l arduino-libraries/RTCZero +pio lib -g install arduino-libraries/RTCZero echo "\e[32mInstalling greygnome/EnableInterrupt\e[0m" -pio pkg install -g -l greygnome/EnableInterrupt +pio lib -g install greygnome/EnableInterrupt echo "\e[32mInstalling greiman/SdFat\e[0m" -pio pkg install -g -l greiman/SdFat +pio lib -g install greiman/SdFat echo "\e[32mInstalling vshymanskyy/TinyGSM\e[0m" -pio pkg install -g -l vshymanskyy/TinyGSM +pio lib -g install vshymanskyy/TinyGSM echo "\e[32mInstalling knolleary/PubSubClient\e[0m" -pio pkg install -g -l knolleary/PubSubClient +pio lib -g install knolleary/PubSubClient echo "\e[32mInstalling adafruit/'Adafruit BusIO'\e[0m" -pio pkg install -g -l adafruit/'Adafruit BusIO' +pio lib -g install adafruit/'Adafruit BusIO' echo "\e[32mInstalling adafruit/'Adafruit Unified Sensor'\e[0m" -pio pkg install -g -l adafruit/'Adafruit Unified Sensor' +pio lib -g install adafruit/'Adafruit Unified Sensor' echo "\e[32mInstalling https://github.com/soligen2010/Adafruit_ADS1X15.git\e[0m" -pio pkg install -g -l https://github.com/soligen2010/Adafruit_ADS1X15.git +pio lib -g install https://github.com/soligen2010/Adafruit_ADS1X15.git echo "\e[32mInstalling adafruit/'Adafruit AM2315'\e[0m" -pio pkg install -g -l adafruit/'Adafruit AM2315' +pio lib -g install adafruit/'Adafruit AM2315' echo "\e[32mInstalling adafruit/'Adafruit BME280 Library'\e[0m" -pio pkg install -g -l adafruit/'Adafruit BME280 Library' +pio lib -g install adafruit/'Adafruit BME280 Library' echo "\e[32mInstalling adafruit/'DHT sensor library'\e[0m" -pio pkg install -g -l adafruit/'DHT sensor library' +pio lib -g install adafruit/'DHT sensor library' echo "\e[32mInstalling adafruit/'Adafruit INA219'\e[0m" -pio pkg install -g -l adafruit/'Adafruit INA219' +pio lib -g install adafruit/'Adafruit INA219' echo "\e[32mInstalling adafruit/'Adafruit MPL115A2'\e[0m" -pio pkg install -g -l adafruit/'Adafruit MPL115A2' +pio lib -g install adafruit/'Adafruit MPL115A2' echo "\e[32mInstalling adafruit/'Adafruit SHT'\e[0m" -pio pkg install -g -l adafruit/'Adafruit SHT4x Library' +pio lib -g install adafruit/'Adafruit SHT4x Library' echo "\e[32mInstalling Martin Lindupp's BMP388 Library\e[0m" -pio pkg install -g -l https://github.com/MartinL1/BMP388_DEV.git +pio lib -g install https://github.com/MartinL1/BMP388_DEV.git echo "\e[32mInstalling paulstoffregen/OneWire\e[0m" -pio pkg install -g -l paulstoffregen/OneWire +pio lib -g install paulstoffregen/OneWire echo "\e[32mInstalling milesburton/DallasTemperature\e[0m" -pio pkg install -g -l milesburton/DallasTemperature +pio lib -g install milesburton/DallasTemperature echo "\e[32mInstalling envirodiy/SDI-12\e[0m" -pio pkg install -g -l envirodiy/SDI-12 +pio lib -g install envirodiy/SDI-12 echo "\e[32mInstalling northernwidget/MS5803\e[0m" -pio pkg install -g -l northernwidget/MS5803 +pio lib -g install northernwidget/MS5803 echo "\e[32mInstalling https://github.com/EnviroDIY/Tally_Library.git#Dev_I2C\e[0m" -pio pkg install -g -l https://github.com/EnviroDIY/Tally_Library.git#Dev_I2C +pio lib -g install https://github.com/EnviroDIY/Tally_Library.git#Dev_I2C echo "\e[32mInstalling envirodiy/SensorModbusMaster\e[0m" -pio pkg install -g -l envirodiy/SensorModbusMaster +pio lib -g install envirodiy/SensorModbusMaster echo "\e[32mInstalling envirodiy/KellerModbus\e[0m" -pio pkg install -g -l envirodiy/KellerModbus +pio lib -g install envirodiy/KellerModbus echo "\e[32mInstalling envirodiy/YosemitechModbus\e[0m" -pio pkg install -g -l envirodiy/YosemitechModbus +pio lib -g install envirodiy/YosemitechModbus echo "\e[32mInstalling vshymanskyy/StreamDebugger\e[0m" -pio pkg install -g -l vshymanskyy/StreamDebugger +pio lib -g install vshymanskyy/StreamDebugger echo "\e[32mInstalling https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git\e[0m" -pio pkg install -g -l https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git +pio lib -g install https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git echo "\e[32mInstalling https://github.com/PaulStoffregen/AltSoftSerial.git\e[0m" -pio pkg install -g -l https://github.com/PaulStoffregen/AltSoftSerial.git +pio lib -g install https://github.com/PaulStoffregen/AltSoftSerial.git echo "\e[32mInstalling https://github.com/SRGDamia1/NeoSWSerial.git\e[0m" -pio pkg install -g -l https://github.com/SRGDamia1/NeoSWSerial.git +pio lib -g install https://github.com/SRGDamia1/NeoSWSerial.git echo "\e[32mInstalling https://github.com/Testato/SoftwareWire.git#v1.5.1\e[0m" -pio pkg install -g -l https://github.com/Testato/SoftwareWire.git#v1.5.1 +pio lib -g install https://github.com/Testato/SoftwareWire.git#v1.5.1 echo "\e[32m\nCurrently installed libraries:\e[0m" pio lib -g list -pio lib list +pio lib list \ No newline at end of file diff --git a/library.json b/library.json index 139bcabd5..09553b1cc 100644 --- a/library.json +++ b/library.json @@ -140,7 +140,7 @@ "owner": "adafruit", "library id": "31", "url": "https://github.com/adafruit/Adafruit_Sensor", - "version": "~1.1.9", + "version": "~1.1.5", "note": "Adafruit's unified sensor library is used by their other libraries", "authors": ["Adafruit"], "frameworks": "arduino", @@ -204,7 +204,7 @@ "owner": "adafruit", "library id": "160", "url": "https://github.com/adafruit/Adafruit_INA219", - "version": "~1.2.1", + "version": "~1.2.0", "note": "This is a library for the Adafruit INA219 high side DC current sensor boards", "authors": ["Adafruit"], "frameworks": "arduino", @@ -225,7 +225,7 @@ "owner": "adafruit", "library id": "11710", "url": "https://github.com/adafruit/Adafruit_SHT4X", - "version": "~1.0.2", + "version": "~1.0.0", "note": "Sensirion SHT4x Library by Adafruit", "authors": ["Adafruit"], "frameworks": "arduino" From 5a8610a1a2b17c261c07741f4ddb8ede7e7cf1b4 Mon Sep 17 00:00:00 2001 From: Anthony Aufdenkampe Date: Tue, 14 Mar 2023 15:55:11 -0500 Subject: [PATCH 020/138] Add RainVUE & Y700 docs to menu readme As suggested by @SRGDamia1 with https://github.com/EnviroDIY/ModularSensors/pull/424#issuecomment-1468537651 --- examples/menu_a_la_carte/ReadMe.md | 32 ++++++++++++++++++++++++------ src/sensors/CampbellRainVUE10.h | 4 ++-- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/examples/menu_a_la_carte/ReadMe.md b/examples/menu_a_la_carte/ReadMe.md index 4a72e3ba1..a04bb6ff4 100644 --- a/examples/menu_a_la_carte/ReadMe.md +++ b/examples/menu_a_la_carte/ReadMe.md @@ -69,15 +69,16 @@ ___ - [Atlas Scientific EZO-EC Conductivity Sensor](#atlas-scientific-ezo-ec-conductivity-sensor) - [Bosch BME280 Environmental Sensor](#bosch-bme280-environmental-sensor) - [Bosch BMP388 and BMP398 Pressure Sensors](#bosch-bmp388-and-bmp398-pressure-sensors) - - [Campbell ClariVUE SDI-12 Turbidity Sensor](#campbell-clarivue-sdi-12-turbidity-sensor) + - [Campbell ClariVUE SDI-12 Turbidity Sensor](#campbell-clarivue-sdi-12-turbidity-sensor) - [Campbell OBS3+ Analog Turbidity Sensor](#campbell-obs3-analog-turbidity-sensor) - - [Decagon CTD-10 Conductivity, Temperature, and Depth Sensor](#decagon-ctd-10-conductivity-temperature-and-depth-sensor) + - [Campbell RainVUE SDI-12 Precipitation Sensor](#campbell-rainvue-sdi-12-precipitation-sensor) + - [Decagon CTD-10 Conductivity, Temperature, and Depth Sensor](#decagon-ctd-10-conductivity-temperature-and-depth-sensor) - [Decagon ES2 Conductivity and Temperature Sensor](#decagon-es2-conductivity-and-temperature-sensor) - - [Everlight ALS-PT19 Ambient Light Sensor](#everlight-als-pt19-ambient-light-sensor) + - [Everlight ALS-PT19 Ambient Light Sensor](#everlight-als-pt19-ambient-light-sensor) - [External Voltage via TI ADS1x15](#external-voltage-via-ti-ads1x15) - [Freescale Semiconductor MPL115A2 Miniature I2C Digital Barometer](#freescale-semiconductor-mpl115a2-miniature-i2c-digital-barometer) - - [In-Situ Aqua/Level TROLL Pressure, Temperature, and Depth Sensor](#in-situ-aqualevel-troll-pressure-temperature-and-depth-sensor) - - [In-Situ RDO PRO-X Rugged Dissolved Oxygen Probe](#in-situ-rdo-pro-x-rugged-dissolved-oxygen-probe) + - [In-Situ Aqua/Level TROLL Pressure, Temperature, and Depth Sensor](#in-situ-aqualevel-troll-pressure-temperature-and-depth-sensor) + - [In-Situ RDO PRO-X Rugged Dissolved Oxygen Probe](#in-situ-rdo-pro-x-rugged-dissolved-oxygen-probe) - [Keller RS485/Modbus Water Level Sensors](#keller-rs485modbus-water-level-sensors) - [Keller Acculevel High Accuracy Submersible Level Transmitter](#keller-acculevel-high-accuracy-submersible-level-transmitter) - [Keller Nanolevel Level Transmitter](#keller-nanolevel-level-transmitter) @@ -90,7 +91,7 @@ ___ - [Meter Teros 11 Soil Moisture Sensor](#meter-teros-11-soil-moisture-sensor) - [PaleoTerra Redox Sensors](#paleoterra-redox-sensors) - [Trinket-Based Tipping Bucket Rain Gauge](#trinket-based-tipping-bucket-rain-gauge) - - [Sensirion SHT4X Digital Humidity and Temperature Sensor](#sensirion-sht4x-digital-humidity-and-temperature-sensor) + - [Sensirion SHT4X Digital Humidity and Temperature Sensor](#sensirion-sht4x-digital-humidity-and-temperature-sensor) - [Northern Widget Tally Event Counter](#northern-widget-tally-event-counter) - [TI INA219 High Side Current Sensor](#ti-ina219-high-side-current-sensor) - [Turner Cyclops-7F Submersible Fluorometer](#turner-cyclops-7f-submersible-fluorometer) @@ -105,6 +106,7 @@ ___ - [Yosemitech Y533 Oxidation Reduction Potential (ORP) Sensor](#yosemitech-y533-oxidation-reduction-potential-orp-sensor) - [Yosemitech Y551 Carbon Oxygen Demand (COD) Sensor with Wiper](#yosemitech-y551-carbon-oxygen-demand-cod-sensor-with-wiper) - [Yosemitech Y560 Ammonium Sensor](#yosemitech-y560-ammonium-sensor) + - [Yosemitech Y700 Pressure Sensor](#yosemitech-y700-pressure-sensor) - [Yosemitech Y4000 Multi-Parameter Sonde](#yosemitech-y4000-multi-parameter-sonde) - [Zebra Tech D-Opto Dissolved Oxygen Sensor](#zebra-tech-d-opto-dissolved-oxygen-sensor) - [Calculated Variables](#calculated-variables) @@ -763,6 +765,15 @@ Note that to access both the high and low range returns, two instances must be c ___ +#### Campbell RainVUE SDI-12 Precipitation Sensor + +@see @ref sensor_rainvue + +[//]: # ( @menusnip{campbell_rainvue10} ) + +___ + + #### Decagon CTD-10 Conductivity, Temperature, and Depth Sensor @see @ref sensor_decagon_ctd @@ -1164,6 +1175,15 @@ ___ ___ +#### Yosemitech Y700 Pressure Sensor + +@see @ref sensor_y700 + +[//]: # ( @menusnip{yosemitech_y700} ) + +___ + + #### Yosemitech Y4000 Multi-Parameter Sonde @see @ref sensor_y4000 diff --git a/src/sensors/CampbellRainVUE10.h b/src/sensors/CampbellRainVUE10.h index 1c0042401..76aa1b1df 100644 --- a/src/sensors/CampbellRainVUE10.h +++ b/src/sensors/CampbellRainVUE10.h @@ -50,9 +50,9 @@ * * ___ * @section sensor_rainvue_examples Example Code - * The Campbell RainVUE10 is used in the @menulink{campbell_rain_vue10} example. + * The Campbell RainVUE10 is used in the @menulink{campbell_rainvue10} example. * - * @menusnip{campbell_rain_vue10} + * @menusnip{campbell_rainvue10} */ /* clang-format on */ From 68d1cca49d1eae09703635ea066fb2d98ff35174 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 15 Mar 2023 12:46:23 -0400 Subject: [PATCH 021/138] Add RainVue and Y700 vars, fix RainVue snake Signed-off-by: Sara Damiano --- examples/menu_a_la_carte/ReadMe.md | 4 ++-- examples/menu_a_la_carte/menu_a_la_carte.ino | 16 +++++++++++++--- src/sensors/CampbellRainVUE10.h | 4 ++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/examples/menu_a_la_carte/ReadMe.md b/examples/menu_a_la_carte/ReadMe.md index a04bb6ff4..4bcac86ac 100644 --- a/examples/menu_a_la_carte/ReadMe.md +++ b/examples/menu_a_la_carte/ReadMe.md @@ -765,11 +765,11 @@ Note that to access both the high and low range returns, two instances must be c ___ -#### Campbell RainVUE SDI-12 Precipitation Sensor +#### Campbell RainVUE SDI-12 Precipitation Sensor @see @ref sensor_rainvue -[//]: # ( @menusnip{campbell_rainvue10} ) +[//]: # ( @menusnip{campbell_rain_vue10} ) ___ diff --git a/examples/menu_a_la_carte/menu_a_la_carte.ino b/examples/menu_a_la_carte/menu_a_la_carte.ino index d6ebad3c2..eaa75eda7 100644 --- a/examples/menu_a_la_carte/menu_a_la_carte.ino +++ b/examples/menu_a_la_carte/menu_a_la_carte.ino @@ -1202,11 +1202,11 @@ Variable* obs3VoltHigh = new CampbellOBS3_Voltage( /** End [campbell_obs3] */ #endif -#if defined BUILD_SENSOR_CAMPBELL_RAINVUE10 +#if defined BUILD_SENSOR_CAMPBELL_RAIN_VUE10 // ========================================================================== // Campbell RainVUE Precipitation Sensor // ========================================================================== -/** Start [campbell_rainvue10] */ +/** Start [campbell_rain_vue10] */ #include // NOTE: Use -1 for any pins that don't apply or aren't being used. @@ -1228,7 +1228,7 @@ Variable* rainvueRainRateAve = new CampbellRainVUE10_RainRateAve( &rainvue, "12345678-abcd-1234-ef00-1234567890ab"); Variable* rainvueRainRateMax = new CampbellRainVUE10_RainRateMax( &rainvue, "12345678-abcd-1234-ef00-1234567890ab"); -/** End [campbell_rainvue10] */ +/** End [campbell_rain_vue10] */ #endif @@ -2512,6 +2512,12 @@ Variable* variableList[] = { obs3TurbHigh, obs3VoltHigh, #endif +#if defined BUILD_SENSOR_CAMPBELL_RAIN_VUE10 + rainvuePrecipitation, + rainvueTips, + rainvueRainRateAve, + rainvueRainRateMax, +#endif #if defined BUILD_SENSOR_DECAGON_CTD ctdCond, ctdTemp, @@ -2659,6 +2665,10 @@ Variable* variableList[] = { y560pH, y560Temp, #endif +#if defined BUILD_SENSOR_YOSEMITECH_Y700 + y700Pres, + y700Temp, +#endif #if defined BUILD_SENSOR_YOSEMITECH_Y4000 y4000DO, y4000Turb, diff --git a/src/sensors/CampbellRainVUE10.h b/src/sensors/CampbellRainVUE10.h index 76aa1b1df..1c0042401 100644 --- a/src/sensors/CampbellRainVUE10.h +++ b/src/sensors/CampbellRainVUE10.h @@ -50,9 +50,9 @@ * * ___ * @section sensor_rainvue_examples Example Code - * The Campbell RainVUE10 is used in the @menulink{campbell_rainvue10} example. + * The Campbell RainVUE10 is used in the @menulink{campbell_rain_vue10} example. * - * @menusnip{campbell_rainvue10} + * @menusnip{campbell_rain_vue10} */ /* clang-format on */ From 0b1eb451815d7ecb8165c9f6d984754758bd7ce2 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 16 Mar 2023 10:14:03 -0400 Subject: [PATCH 022/138] fix structure of uninstall for release package Signed-off-by: Sara Damiano --- .github/workflows/prepare_release.yaml | 16 ++++++++-------- ChangeLog.md | 3 ++- docs/FAQ/Processor-Compatibility.md | 18 +++++++++--------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/.github/workflows/prepare_release.yaml b/.github/workflows/prepare_release.yaml index d74a021d5..5cec36abb 100644 --- a/.github/workflows/prepare_release.yaml +++ b/.github/workflows/prepare_release.yaml @@ -54,50 +54,50 @@ jobs: continue-on-error: true run: | echo "::debug::Removing Adafruit GFX Library" - pio pkg uninstall --library -g adafruit/Adafruit GFX Library + pio pkg uninstall --library -g "adafruit/Adafruit GFX Library" - name: Uninstall Adafruit NeoPixel library continue-on-error: true run: | echo "::debug::Removing Adafruit NeoPixel" - pio pkg uninstall --library -g adafruit/Adafruit NeoPixel + pio pkg uninstall --library -g "adafruit/Adafruit NeoPixel" - name: Uninstall Adafruit SSD1306 library continue-on-error: true run: | echo "::debug::Removing Adafruit SSD1306" - pio pkg uninstall --library -g adafruit/Adafruit SSD1306 + pio pkg uninstall --library -g "adafruit/Adafruit SSD1306" - name: Uninstall Adafruit ADXL343 library continue-on-error: true run: | echo "::debug::Removing Adafruit ADXL343" - pio pkg uninstall --library -g adafruit/Adafruit ADXL343 + pio pkg uninstall --library -g "adafruit/Adafruit ADXL343" - name: Uninstall Adafruit STMPE610 library continue-on-error: true run: | echo "::debug::Removing Adafruit STMPE610" - pio pkg uninstall --library -g adafruit/Adafruit STMPE610 + pio pkg uninstall --library -g "adafruit/Adafruit STMPE610" - name: Uninstall Adafruit TouchScreen library continue-on-error: true run: | echo "::debug::Removing Adafruit TouchScreen" - pio pkg uninstall --library -g adafruit/Adafruit TouchScreen + pio pkg uninstall --library -g "adafruit/Adafruit TouchScreen" - name: Uninstall Adafruit ILI9341 library continue-on-error: true run: | echo "::debug::Removing Adafruit ILI9341" - pio pkg uninstall --library -g adafruit/Adafruit ILI9341 + pio pkg uninstall --library -g "adafruit/Adafruit ILI9341" # zip up all the installed libraries # need to cd into the pio directory so we don't get extra junk directories - name: Zip libraries run: | echo "::debug::Listing global libraries" - pio pkg list --library -g -v + pio pkg list -g -v --only-libraries¶ echo "::debug::Zipping global libraries" cd /home/runner/.platformio/ zip ${{ env.ZIP_NAME }}.zip -r lib diff --git a/ChangeLog.md b/ChangeLog.md index c9f207645..d61614299 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -34,7 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Specify python version 3.x for actions (used by PlatformIO) ### Added -- Support Campbell RainVUE10 SDI-12 Precipitation Sensor (#416) +- Support Campbell RainVUE10 SDI-12 Precipitation Sensor [#416](https://github.com/EnviroDIY/ModularSensors/issues/416) - Support YosemiTech Y700 Pressor Sensor ([#421](https://github.com/EnviroDIY/ModularSensors/issues/421)) ### Removed @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed non-concurrent data fetch for SDI-12 when *NOT* using debugging. - Fixed internet connection when in "testing mode" - Allow a non-zero wait time for SDI-12 sensors +- Fixed outdated GitHub actions *** diff --git a/docs/FAQ/Processor-Compatibility.md b/docs/FAQ/Processor-Compatibility.md index 0bfde1557..73c153218 100644 --- a/docs/FAQ/Processor-Compatibility.md +++ b/docs/FAQ/Processor-Compatibility.md @@ -5,18 +5,18 @@ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) -- [Processor Compatibility](#processor-compatibility) - - [AtMega1284p (EnviroDIY Mayfly, Sodaq Mbili, Mighty 1284)](#atmega1284p-envirodiy-mayfly-sodaq-mbili-mighty-1284) - - [AtSAMD21 (Arduino Zero, Adafruit Feather M0, Sodaq Autonomo)](#atsamd21-arduino-zero-adafruit-feather-m0-sodaq-autonomo) - - [AtMega2560 (Arduino Mega)](#atmega2560-arduino-mega) - - [AtMega644p (Sanguino)](#atmega644p-sanguino) - - [AtMega328p (Arduino Uno, Duemilanove, LilyPad, Mini, Seeeduino Stalker, etc)](#atmega328p-arduino-uno-duemilanove-lilypad-mini-seeeduino-stalker-etc) - - [AtMega32u4 (Arduino Leonardo/Micro, Adafruit Flora/Feather, etc)](#atmega32u4-arduino-leonardomicro-adafruit-florafeather-etc) - - [Unsupported Processors](#unsupported-processors) +- [Processor Compatibility ](#processor-compatibility-) + - [AtMega1284p (EnviroDIY Mayfly, Sodaq Mbili, Mighty 1284) ](#atmega1284p-envirodiy-mayfly-sodaq-mbili-mighty-1284-) + - [AtSAMD21 (Arduino Zero, Adafruit Feather M0, Sodaq Autonomo) ](#atsamd21-arduino-zero-adafruit-feather-m0-sodaq-autonomo-) + - [AtMega2560 (Arduino Mega) ](#atmega2560-arduino-mega-) + - [AtMega644p (Sanguino) ](#atmega644p-sanguino-) + - [AtMega328p (Arduino Uno, Duemilanove, LilyPad, Mini, Seeeduino Stalker, etc) ](#atmega328p-arduino-uno-duemilanove-lilypad-mini-seeeduino-stalker-etc-) + - [AtMega32u4 (Arduino Leonardo/Micro, Adafruit Flora/Feather, etc) ](#atmega32u4-arduino-leonardomicro-adafruit-florafeather-etc-) + - [Unsupported Processors ](#unsupported-processors-) [//]: # ( End GitHub Only ) -## AtMega1284p ([EnviroDIY Mayfly](https://envirodiy.org/mayfly/), Sodaq Mbili, Mighty 1284) +## AtMega1284p (EnviroDIY Mayfly, Sodaq Mbili, Mighty 1284) The [EnviroDIY Mayfly](https://envirodiy.org/mayfly/) _is_ the test board for this library. _Everything_ is designed to work with this processor. From 0796c591028eba689378b0dccf1c05af2fcee0f7 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 16 Mar 2023 10:32:25 -0400 Subject: [PATCH 023/138] Another tweak to auto release [ci skip] Signed-off-by: Sara Damiano --- .github/workflows/prepare_release.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/prepare_release.yaml b/.github/workflows/prepare_release.yaml index 5cec36abb..3eacfbfc6 100644 --- a/.github/workflows/prepare_release.yaml +++ b/.github/workflows/prepare_release.yaml @@ -47,57 +47,57 @@ jobs: - name: Install ModularSensors from the master branch run: | - pio pkg install -g --library https://github.com/EnviroDIY/ModularSensors + pio pkg install -g -l https://github.com/EnviroDIY/ModularSensors # Uninstall graphics libraries from Adafruit - name: Uninstall Adafruit GFX Library library continue-on-error: true run: | echo "::debug::Removing Adafruit GFX Library" - pio pkg uninstall --library -g "adafruit/Adafruit GFX Library" + pio pkg uninstall -g -l "adafruit/Adafruit GFX Library" - name: Uninstall Adafruit NeoPixel library continue-on-error: true run: | echo "::debug::Removing Adafruit NeoPixel" - pio pkg uninstall --library -g "adafruit/Adafruit NeoPixel" + pio pkg uninstall -g -l "adafruit/Adafruit NeoPixel" - name: Uninstall Adafruit SSD1306 library continue-on-error: true run: | echo "::debug::Removing Adafruit SSD1306" - pio pkg uninstall --library -g "adafruit/Adafruit SSD1306" + pio pkg uninstall -g -l "adafruit/Adafruit SSD1306" - name: Uninstall Adafruit ADXL343 library continue-on-error: true run: | echo "::debug::Removing Adafruit ADXL343" - pio pkg uninstall --library -g "adafruit/Adafruit ADXL343" + pio pkg uninstall -g -l "adafruit/Adafruit ADXL343" - name: Uninstall Adafruit STMPE610 library continue-on-error: true run: | echo "::debug::Removing Adafruit STMPE610" - pio pkg uninstall --library -g "adafruit/Adafruit STMPE610" + pio pkg uninstall -g -l "adafruit/Adafruit STMPE610" - name: Uninstall Adafruit TouchScreen library continue-on-error: true run: | echo "::debug::Removing Adafruit TouchScreen" - pio pkg uninstall --library -g "adafruit/Adafruit TouchScreen" + pio pkg uninstall -g -l "adafruit/Adafruit TouchScreen" - name: Uninstall Adafruit ILI9341 library continue-on-error: true run: | echo "::debug::Removing Adafruit ILI9341" - pio pkg uninstall --library -g "adafruit/Adafruit ILI9341" + pio pkg uninstall -g -l "adafruit/Adafruit ILI9341" # zip up all the installed libraries # need to cd into the pio directory so we don't get extra junk directories - name: Zip libraries run: | echo "::debug::Listing global libraries" - pio pkg list -g -v --only-libraries¶ + pio pkg list -g -v --only-libraries echo "::debug::Zipping global libraries" cd /home/runner/.platformio/ zip ${{ env.ZIP_NAME }}.zip -r lib From e958fe299dd6bdde75a7ff752e5a2365d6f8898e Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 16 Mar 2023 11:17:05 -0400 Subject: [PATCH 024/138] Fix typo in refs, upgrade doxyfile [ci skip] Signed-off-by: Sara Damiano --- .github/workflows/build_documentation.yaml | 2 +- .gitignore | 1 + docs/Doxyfile | 219 +++++++++++------- examples/DRWI_Mayfly1_WiFi/ReadMe.md | 6 +- examples/menu_a_la_carte/ReadMe.md | 244 ++++++++++----------- src/sensors/CampbellRainVUE10.h | 2 +- 6 files changed, 272 insertions(+), 202 deletions(-) diff --git a/.github/workflows/build_documentation.yaml b/.github/workflows/build_documentation.yaml index b6b6e61e4..c5d2fdf20 100644 --- a/.github/workflows/build_documentation.yaml +++ b/.github/workflows/build_documentation.yaml @@ -131,7 +131,7 @@ jobs: path: code_docs/m.css - name: Generate all the documentation - continue-on-error: true + continue-on-error: false run: | cd ${{ github.workspace }}/code_docs/ModularSensors/ chmod +x continuous_integration/generate-documentation.sh diff --git a/.gitignore b/.gitignore index 4b2fe4792..f668ae57c 100644 --- a/.gitignore +++ b/.gitignore @@ -108,3 +108,4 @@ compile_results.log continuous_integration_artifacts/* arduino_cli.log **/sensor_tests/* +docs/Doxyfile.bak diff --git a/docs/Doxyfile b/docs/Doxyfile index 1ad894e22..db06a11c2 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.9.3 +# Doxyfile 1.9.6 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -12,6 +12,16 @@ # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options @@ -60,16 +70,28 @@ PROJECT_LOGO = ModularSensors_ubuntu_264x55.png OUTPUT_DIRECTORY = ../../ModularSensorsDoxygen -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes -# performance problems for the file system. +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. # The default value is: NO. CREATE_SUBDIRS = NO +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode @@ -81,14 +103,14 @@ ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English @@ -277,10 +299,9 @@ ALIASES = "license=@par License:\n" \ "m_since{2}=@since @m_class{m-label m-success m-flat} @ref changelog-\1-\2 \"since v\1.\2\"" \ "m_deprecated_since{3}=@since deprecated in v\1.\2.\3 @deprecated" \ "menulink{1}=[menu a la carte](@ref menu_walk_\1)" \ - "menusnip{1}=@snippet{lineno} menu_a_la_carte.ino \1 ^^ ^^ " \ + "menusnip{1}=@snippet{lineno} menu_a_la_carte.ino \1 ^^ ^^" \ "m_innerpage{1}=@xmlonly @endxmlonly" - # "menulink{1}=[menu a la carte](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_\1)" \ # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all @@ -470,7 +491,7 @@ TYPEDEF_HIDES_STRUCT = NO LOOKUP_CACHE_SIZE = 0 -# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use # during processing. When set to 0 doxygen will based this on the number of # cores available in the system. You can set it explicitly to a value larger # than 0 to get more control over the balance between CPU load and processing @@ -564,7 +585,8 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO @@ -595,14 +617,15 @@ INTERNAL_DOCS = NO # filesystem is case sensitive (i.e. it supports files in the same directory # whose names only differ in casing), the option must be set to YES to properly # deal with such files in case they appear in the input. For filesystems that -# are not case sensitive the option should be be set to NO to properly deal with +# are not case sensitive the option should be set to NO to properly deal with # output files written for symbols that only differ in casing, such as for two # classes, one named CLASS and the other named Class, and to also support # references to files without having to specify the exact matching casing. On # Windows (including Cygwin) and MacOS, users should typically set this option # to NO, whereas on Linux or other Unix flavors it should typically be set to # YES. -# The default value is: system dependent. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. CASE_SENSE_NAMES = NO @@ -854,6 +877,14 @@ WARN_IF_INCOMPLETE_DOC = YES WARN_NO_PARAMDOC = YES +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = YES + # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when # a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS # then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but @@ -869,10 +900,21 @@ WARN_AS_ERROR = FAIL_ON_WARNINGS # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). In case the file specified cannot be opened for writing the @@ -892,10 +934,6 @@ WARN_LOGFILE = output_doxygen.log # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -# INPUT = ../README.md \ -# ../src \ -# ../examples \ -# ../docs INPUT = .. # This tag can be used to specify the character encoding of the source files @@ -903,10 +941,21 @@ INPUT = .. # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: # https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING # The default value is: UTF-8. INPUT_ENCODING = UTF-8 +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. @@ -1039,6 +1088,11 @@ IMAGE_PATH = # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. @@ -1080,6 +1134,15 @@ FILTER_SOURCE_PATTERNS = USE_MDFILE_AS_MAINPAGE = README.md +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- @@ -1175,7 +1238,7 @@ VERBATIM_HEADERS = YES # generated with the -Duse_libclang=ON option for CMake. # The default value is: NO. -# CLANG_ASSISTED_PARSING = NO +CLANG_ASSISTED_PARSING = NO # If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS # tag is set to YES then doxygen will add the directory of each input to the @@ -1183,7 +1246,7 @@ VERBATIM_HEADERS = YES # The default value is: YES. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. -# CLANG_ADD_INC_PATHS = YES +CLANG_ADD_INC_PATHS = YES # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that @@ -1191,7 +1254,7 @@ VERBATIM_HEADERS = YES # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. -# CLANG_OPTIONS = +CLANG_OPTIONS = # If clang assisted parsing is enabled you can provide the clang parser with the # path to the directory containing a file called compile_commands.json. This @@ -1204,7 +1267,7 @@ VERBATIM_HEADERS = YES # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse_libclang=ON option for CMake. -# CLANG_DATABASE_PATH = +CLANG_DATABASE_PATH = #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index @@ -1217,10 +1280,11 @@ VERBATIM_HEADERS = YES ALPHABETICAL_INDEX = YES -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = @@ -1299,7 +1363,12 @@ HTML_STYLESHEET = # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1314,6 +1383,19 @@ HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a color-wheel, see @@ -1677,17 +1759,6 @@ HTML_FORMULA_FORMAT = png FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANSPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - # The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands # to create new LaTeX commands to be used in formulas as building blocks. See # the section "Including formulas" for details. @@ -2204,10 +2275,6 @@ DOCBOOK_OUTPUT = docbook GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# Configuration options related to Sqlite3 output -#--------------------------------------------------------------------------- - #--------------------------------------------------------------------------- # Configuration options related to the Perl module output #--------------------------------------------------------------------------- @@ -2282,7 +2349,8 @@ SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the -# preprocessor. +# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of +# RECURSIVE has no effect here. # This tag requires that the tag SEARCH_INCLUDES is set to YES. INCLUDE_PATH = ../src \ @@ -2458,26 +2526,38 @@ HAVE_DOT = YES DOT_NUM_THREADS = 0 -# When you want a differently looking font in the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. +# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of +# subgraphs. When you want a differently looking font in the dot files that +# doxygen generates you can specify fontname, fontcolor and fontsize attributes. +# For details please see Node, +# Edge and Graph Attributes specification You need to make sure dot is able +# to find the font, which can be done by putting it in a standard location or by +# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. Default graphviz fontsize is 14. +# The default value is: fontname=Helvetica,fontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTNAME = Helvetica +DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. +# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can +# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. Complete documentation about +# arrows shapes. +# The default value is: labelfontname=Helvetica,labelfontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTSIZE = 10 +DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10" -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. +# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes +# around nodes set 'shape=plain' or 'shape=plaintext' Shapes specification +# The default value is: shape=box,height=0.2,width=0.4. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" + +# You can set the path where dot can find font specified with fontname in +# DOT_COMMON_ATTR and others dot attributes. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTPATH = @@ -2503,7 +2583,8 @@ CLASS_GRAPH = YES COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. +# groups, showing the direct groups dependencies. See also the chapter Grouping +# in the manual. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2719,18 +2800,6 @@ DOT_GRAPH_MAX_NODES = 500 MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = NO - # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support diff --git a/examples/DRWI_Mayfly1_WiFi/ReadMe.md b/examples/DRWI_Mayfly1_WiFi/ReadMe.md index 414aed594..b870bba2f 100644 --- a/examples/DRWI_Mayfly1_WiFi/ReadMe.md +++ b/examples/DRWI_Mayfly1_WiFi/ReadMe.md @@ -19,8 +19,8 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) -- [DRWI Sites with a Mayfly 1.x and EnviroDIY ESP32 WiFi Bees](#drwi-sites-with-a-mayfly-1x-and-envirodiy-esp32-wifi-bees) -- [Unique Features of the DRWI Mayfly 1.x WiFi Example](#unique-features-of-the-drwi-mayfly-1x-wifi-example) +- [DRWI Sites with a Mayfly 1.x and EnviroDIY ESP32 WiFi Bees ](#drwi-sites-with-a-mayfly-1x-and-envirodiy-esp32-wifi-bees-) +- [Unique Features of the DRWI Mayfly 1.x WiFi Example ](#unique-features-of-the-drwi-mayfly-1x-wifi-example-) [//]: # ( End GitHub Only ) @@ -37,4 +37,4 @@ _______ [//]: # ( @section example_drwi_mayfly1_wifi_code The Complete Code ) -[//]: # ( @include{lineno} DRWI_Mayfly1_WiFi/DRWI_Mayfly1_._WiFi.ino ) +[//]: # ( @include{lineno} DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino ) diff --git a/examples/menu_a_la_carte/ReadMe.md b/examples/menu_a_la_carte/ReadMe.md index 4bcac86ac..34fb35438 100644 --- a/examples/menu_a_la_carte/ReadMe.md +++ b/examples/menu_a_la_carte/ReadMe.md @@ -24,127 +24,127 @@ ___ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) -- [Example showing all possible functionality](#example-showing-all-possible-functionality) -- [Walking Through the Code](#walking-through-the-code) - - [Defines and Includes](#defines-and-includes) - - [Defines for the Arduino IDE](#defines-for-the-arduino-ide) - - [Library Includes](#library-includes) - - [Logger Settings](#logger-settings) - - [Creating Extra Serial Ports](#creating-extra-serial-ports) - - [AVR Boards](#avr-boards) - - [AltSoftSerial](#altsoftserial) - - [NeoSWSerial](#neoswserial) - - [SoftwareSerial with External Interrupts](#softwareserial-with-external-interrupts) - - [Software I2C/Wire](#software-i2cwire) - - [SAMD Boards](#samd-boards) - - [Assigning Serial Port Functionality](#assigning-serial-port-functionality) - - [Logging Options](#logging-options) - - [Wifi/Cellular Modem Options](#wificellular-modem-options) - - [Digi XBee Cellular - Transparent Mode](#digi-xbee-cellular---transparent-mode) - - [Digi XBee3 LTE-M - Bypass Mode](#digi-xbee3-lte-m---bypass-mode) - - [Digi XBee 3G - Bypass Mode](#digi-xbee-3g---bypass-mode) - - [Digi XBee S6B Wifi](#digi-xbee-s6b-wifi) - - [Espressif ESP8266](#espressif-esp8266) - - [Quectel BG96](#quectel-bg96) - - [Sequans Monarch](#sequans-monarch) - - [SIMCom SIM800](#simcom-sim800) - - [SIMCom SIM7000](#simcom-sim7000) - - [SIMCom SIM7080G (EnviroDIY LTE Bee])](#simcom-sim7080g-envirodiy-lte-bee) - - [Sodaq GPRSBee](#sodaq-gprsbee) - - [u-blox SARA R410M](#u-blox-sara-r410m) - - [u-blox SARA U201](#u-blox-sara-u201) - - [Modem Measured Variables](#modem-measured-variables) - - [Sensors and Measured Variables](#sensors-and-measured-variables) - - [The processor as a sensor](#the-processor-as-a-sensor) - - [Maxim DS3231 RTC as a sensor](#maxim-ds3231-rtc-as-a-sensor) - - [AOSong AM2315](#aosong-am2315) - - [AOSong DHT](#aosong-dht) - - [Apogee SQ-212 Quantum Light Sensor](#apogee-sq-212-quantum-light-sensor) - - [Atlas Scientific EZO Circuits](#atlas-scientific-ezo-circuits) - - [Atlas Scientific EZO-CO2 Embedded NDIR Carbon Dioxide Sensor](#atlas-scientific-ezo-co2-embedded-ndir-carbon-dioxide-sensor) - - [Atlas Scientific EZO-DO Dissolved Oxygen Sensor](#atlas-scientific-ezo-do-dissolved-oxygen-sensor) - - [Atlas Scientific EZO-ORP Oxidation/Reduction Potential Sensor](#atlas-scientific-ezo-orp-oxidationreduction-potential-sensor) - - [Atlas Scientific EZO-pH Sensor](#atlas-scientific-ezo-ph-sensor) - - [Atlas Scientific EZO-RTD Temperature Sensor](#atlas-scientific-ezo-rtd-temperature-sensor) - - [Atlas Scientific EZO-EC Conductivity Sensor](#atlas-scientific-ezo-ec-conductivity-sensor) - - [Bosch BME280 Environmental Sensor](#bosch-bme280-environmental-sensor) - - [Bosch BMP388 and BMP398 Pressure Sensors](#bosch-bmp388-and-bmp398-pressure-sensors) - - [Campbell ClariVUE SDI-12 Turbidity Sensor](#campbell-clarivue-sdi-12-turbidity-sensor) - - [Campbell OBS3+ Analog Turbidity Sensor](#campbell-obs3-analog-turbidity-sensor) - - [Campbell RainVUE SDI-12 Precipitation Sensor](#campbell-rainvue-sdi-12-precipitation-sensor) - - [Decagon CTD-10 Conductivity, Temperature, and Depth Sensor](#decagon-ctd-10-conductivity-temperature-and-depth-sensor) - - [Decagon ES2 Conductivity and Temperature Sensor](#decagon-es2-conductivity-and-temperature-sensor) - - [Everlight ALS-PT19 Ambient Light Sensor](#everlight-als-pt19-ambient-light-sensor) - - [External Voltage via TI ADS1x15](#external-voltage-via-ti-ads1x15) - - [Freescale Semiconductor MPL115A2 Miniature I2C Digital Barometer](#freescale-semiconductor-mpl115a2-miniature-i2c-digital-barometer) - - [In-Situ Aqua/Level TROLL Pressure, Temperature, and Depth Sensor](#in-situ-aqualevel-troll-pressure-temperature-and-depth-sensor) - - [In-Situ RDO PRO-X Rugged Dissolved Oxygen Probe](#in-situ-rdo-pro-x-rugged-dissolved-oxygen-probe) - - [Keller RS485/Modbus Water Level Sensors](#keller-rs485modbus-water-level-sensors) - - [Keller Acculevel High Accuracy Submersible Level Transmitter](#keller-acculevel-high-accuracy-submersible-level-transmitter) - - [Keller Nanolevel Level Transmitter](#keller-nanolevel-level-transmitter) - - [Maxbotix HRXL Ultrasonic Range Finder](#maxbotix-hrxl-ultrasonic-range-finder) - - [Maxim DS18 One Wire Temperature Sensor](#maxim-ds18-one-wire-temperature-sensor) - - [Measurement Specialties MS5803-14BA Pressure Sensor](#measurement-specialties-ms5803-14ba-pressure-sensor) - - [Meter SDI-12 Sensors](#meter-sdi-12-sensors) - - [Meter ECH2O Soil Moisture Sensor](#meter-ech2o-soil-moisture-sensor) - - [Meter Hydros 21 Conductivity, Temperature, and Depth Sensor](#meter-hydros-21-conductivity-temperature-and-depth-sensor) - - [Meter Teros 11 Soil Moisture Sensor](#meter-teros-11-soil-moisture-sensor) - - [PaleoTerra Redox Sensors](#paleoterra-redox-sensors) - - [Trinket-Based Tipping Bucket Rain Gauge](#trinket-based-tipping-bucket-rain-gauge) - - [Sensirion SHT4X Digital Humidity and Temperature Sensor](#sensirion-sht4x-digital-humidity-and-temperature-sensor) - - [Northern Widget Tally Event Counter](#northern-widget-tally-event-counter) - - [TI INA219 High Side Current Sensor](#ti-ina219-high-side-current-sensor) - - [Turner Cyclops-7F Submersible Fluorometer](#turner-cyclops-7f-submersible-fluorometer) - - [Analog Electrical Conductivity using the Processor's Analog Pins](#analog-electrical-conductivity-using-the-processors-analog-pins) - - [Yosemitech RS485/Modbus Environmental Sensors](#yosemitech-rs485modbus-environmental-sensors) - - [Yosemitech Y504 Dissolved Oxygen Sensor](#yosemitech-y504-dissolved-oxygen-sensor) - - [Yosemitech Y510 Turbidity Sensor](#yosemitech-y510-turbidity-sensor) - - [Yosemitech Y511 Turbidity Sensor with Wiper](#yosemitech-y511-turbidity-sensor-with-wiper) - - [Yosemitech Y514 Chlorophyll Sensor](#yosemitech-y514-chlorophyll-sensor) - - [Yosemitech Y520 Conductivity Sensor](#yosemitech-y520-conductivity-sensor) - - [Yosemitech Y532 pH Sensor](#yosemitech-y532-ph-sensor) - - [Yosemitech Y533 Oxidation Reduction Potential (ORP) Sensor](#yosemitech-y533-oxidation-reduction-potential-orp-sensor) - - [Yosemitech Y551 Carbon Oxygen Demand (COD) Sensor with Wiper](#yosemitech-y551-carbon-oxygen-demand-cod-sensor-with-wiper) - - [Yosemitech Y560 Ammonium Sensor](#yosemitech-y560-ammonium-sensor) - - [Yosemitech Y700 Pressure Sensor](#yosemitech-y700-pressure-sensor) - - [Yosemitech Y4000 Multi-Parameter Sonde](#yosemitech-y4000-multi-parameter-sonde) - - [Zebra Tech D-Opto Dissolved Oxygen Sensor](#zebra-tech-d-opto-dissolved-oxygen-sensor) - - [Calculated Variables](#calculated-variables) - - [Creating the array, logger, publishers](#creating-the-array-logger-publishers) - - [The variable array](#the-variable-array) - - [Creating Variables within an Array](#creating-variables-within-an-array) - - [Creating Variables and Pasting UUIDs from MonitorMyWatershed](#creating-variables-and-pasting-uuids-from-monitormywatershed) - - [Creating Variables within an Array](#creating-variables-within-an-array-1) - - [The Logger Object](#the-logger-object) - - [Data Publishers](#data-publishers) - - [Monitor My Watershed](#monitor-my-watershed) - - [DreamHost](#dreamhost) - - [ThingSpeak](#thingspeak) - - [Ubidots](#ubidots) - - [Extra Working Functions](#extra-working-functions) - - [Arduino Setup Function](#arduino-setup-function) - - [Starting the Function](#starting-the-function) - - [Wait for USB](#wait-for-usb) - - [Printing a Hello](#printing-a-hello) - - [Serial Interrupts](#serial-interrupts) - - [Serial Begin](#serial-begin) - - [SAMD Pin Peripherals](#samd-pin-peripherals) - - [Flash the LEDs](#flash-the-leds) - - [Begin the Logger](#begin-the-logger) - - [Setup the Sensors](#setup-the-sensors) - - [Custom Modem Setup](#custom-modem-setup) - - [ESP8266 Baud Rate](#esp8266-baud-rate) - - [Skywire Pin Inversions](#skywire-pin-inversions) - - [SimCom SIM7080G Network Mode](#simcom-sim7080g-network-mode) - - [XBee Cellular Carrier](#xbee-cellular-carrier) - - [SARA R4 Cellular Carrier](#sara-r4-cellular-carrier) - - [Sync the Real Time Clock](#sync-the-real-time-clock) - - [Setup File on the SD card](#setup-file-on-the-sd-card) - - [Sleep until the First Data Collection Time](#sleep-until-the-first-data-collection-time) - - [Setup Complete](#setup-complete) - - [Arduino Loop Function](#arduino-loop-function) - - [A Typical Loop](#a-typical-loop) - - [A Complex Loop](#a-complex-loop) +- [Example showing all possible functionality ](#example-showing-all-possible-functionality-) +- [Walking Through the Code ](#walking-through-the-code-) + - [Defines and Includes ](#defines-and-includes-) + - [Defines for the Arduino IDE ](#defines-for-the-arduino-ide-) + - [Library Includes ](#library-includes-) + - [Logger Settings ](#logger-settings-) + - [Creating Extra Serial Ports ](#creating-extra-serial-ports-) + - [AVR Boards ](#avr-boards-) + - [AltSoftSerial ](#altsoftserial-) + - [NeoSWSerial ](#neoswserial-) + - [SoftwareSerial with External Interrupts ](#softwareserial-with-external-interrupts-) + - [Software I2C/Wire ](#software-i2cwire-) + - [SAMD Boards ](#samd-boards-) + - [Assigning Serial Port Functionality ](#assigning-serial-port-functionality-) + - [Logging Options ](#logging-options-) + - [Wifi/Cellular Modem Options ](#wificellular-modem-options-) + - [Digi XBee Cellular - Transparent Mode ](#digi-xbee-cellular---transparent-mode-) + - [Digi XBee3 LTE-M - Bypass Mode ](#digi-xbee3-lte-m---bypass-mode-) + - [Digi XBee 3G - Bypass Mode ](#digi-xbee-3g---bypass-mode-) + - [Digi XBee S6B Wifi ](#digi-xbee-s6b-wifi-) + - [Espressif ESP8266 ](#espressif-esp8266-) + - [Quectel BG96 ](#quectel-bg96-) + - [Sequans Monarch ](#sequans-monarch-) + - [SIMCom SIM800 ](#simcom-sim800-) + - [SIMCom SIM7000 ](#simcom-sim7000-) + - [SIMCom SIM7080G (EnviroDIY LTE Bee\]) ](#simcom-sim7080g-envirodiy-lte-bee-) + - [Sodaq GPRSBee ](#sodaq-gprsbee-) + - [u-blox SARA R410M ](#u-blox-sara-r410m-) + - [u-blox SARA U201 ](#u-blox-sara-u201-) + - [Modem Measured Variables ](#modem-measured-variables-) + - [Sensors and Measured Variables ](#sensors-and-measured-variables-) + - [The processor as a sensor ](#the-processor-as-a-sensor-) + - [Maxim DS3231 RTC as a sensor ](#maxim-ds3231-rtc-as-a-sensor-) + - [AOSong AM2315 ](#aosong-am2315-) + - [AOSong DHT ](#aosong-dht-) + - [Apogee SQ-212 Quantum Light Sensor ](#apogee-sq-212-quantum-light-sensor-) + - [Atlas Scientific EZO Circuits ](#atlas-scientific-ezo-circuits-) + - [Atlas Scientific EZO-CO2 Embedded NDIR Carbon Dioxide Sensor ](#atlas-scientific-ezo-co2-embedded-ndir-carbon-dioxide-sensor-) + - [Atlas Scientific EZO-DO Dissolved Oxygen Sensor ](#atlas-scientific-ezo-do-dissolved-oxygen-sensor-) + - [Atlas Scientific EZO-ORP Oxidation/Reduction Potential Sensor ](#atlas-scientific-ezo-orp-oxidationreduction-potential-sensor-) + - [Atlas Scientific EZO-pH Sensor ](#atlas-scientific-ezo-ph-sensor-) + - [Atlas Scientific EZO-RTD Temperature Sensor ](#atlas-scientific-ezo-rtd-temperature-sensor-) + - [Atlas Scientific EZO-EC Conductivity Sensor ](#atlas-scientific-ezo-ec-conductivity-sensor-) + - [Bosch BME280 Environmental Sensor ](#bosch-bme280-environmental-sensor-) + - [Bosch BMP388 and BMP398 Pressure Sensors ](#bosch-bmp388-and-bmp398-pressure-sensors-) + - [Campbell ClariVUE SDI-12 Turbidity Sensor ](#campbell-clarivue-sdi-12-turbidity-sensor-) + - [Campbell OBS3+ Analog Turbidity Sensor ](#campbell-obs3-analog-turbidity-sensor-) + - [Campbell RainVUE SDI-12 Precipitation Sensor ](#campbell-rainvue-sdi-12-precipitation-sensor-) + - [Decagon CTD-10 Conductivity, Temperature, and Depth Sensor ](#decagon-ctd-10-conductivity-temperature-and-depth-sensor-) + - [Decagon ES2 Conductivity and Temperature Sensor ](#decagon-es2-conductivity-and-temperature-sensor-) + - [Everlight ALS-PT19 Ambient Light Sensor ](#everlight-als-pt19-ambient-light-sensor-) + - [External Voltage via TI ADS1x15 ](#external-voltage-via-ti-ads1x15-) + - [Freescale Semiconductor MPL115A2 Miniature I2C Digital Barometer ](#freescale-semiconductor-mpl115a2-miniature-i2c-digital-barometer-) + - [In-Situ Aqua/Level TROLL Pressure, Temperature, and Depth Sensor ](#in-situ-aqualevel-troll-pressure-temperature-and-depth-sensor-) + - [In-Situ RDO PRO-X Rugged Dissolved Oxygen Probe ](#in-situ-rdo-pro-x-rugged-dissolved-oxygen-probe-) + - [Keller RS485/Modbus Water Level Sensors ](#keller-rs485modbus-water-level-sensors-) + - [Keller Acculevel High Accuracy Submersible Level Transmitter ](#keller-acculevel-high-accuracy-submersible-level-transmitter-) + - [Keller Nanolevel Level Transmitter ](#keller-nanolevel-level-transmitter-) + - [Maxbotix HRXL Ultrasonic Range Finder ](#maxbotix-hrxl-ultrasonic-range-finder-) + - [Maxim DS18 One Wire Temperature Sensor ](#maxim-ds18-one-wire-temperature-sensor-) + - [Measurement Specialties MS5803-14BA Pressure Sensor ](#measurement-specialties-ms5803-14ba-pressure-sensor-) + - [Meter SDI-12 Sensors ](#meter-sdi-12-sensors-) + - [Meter ECH2O Soil Moisture Sensor ](#meter-ech2o-soil-moisture-sensor-) + - [Meter Hydros 21 Conductivity, Temperature, and Depth Sensor ](#meter-hydros-21-conductivity-temperature-and-depth-sensor-) + - [Meter Teros 11 Soil Moisture Sensor ](#meter-teros-11-soil-moisture-sensor-) + - [PaleoTerra Redox Sensors ](#paleoterra-redox-sensors-) + - [Trinket-Based Tipping Bucket Rain Gauge ](#trinket-based-tipping-bucket-rain-gauge-) + - [Sensirion SHT4X Digital Humidity and Temperature Sensor ](#sensirion-sht4x-digital-humidity-and-temperature-sensor-) + - [Northern Widget Tally Event Counter ](#northern-widget-tally-event-counter-) + - [TI INA219 High Side Current Sensor ](#ti-ina219-high-side-current-sensor-) + - [Turner Cyclops-7F Submersible Fluorometer ](#turner-cyclops-7f-submersible-fluorometer-) + - [Analog Electrical Conductivity using the Processor's Analog Pins ](#analog-electrical-conductivity-using-the-processors-analog-pins-) + - [Yosemitech RS485/Modbus Environmental Sensors ](#yosemitech-rs485modbus-environmental-sensors-) + - [Yosemitech Y504 Dissolved Oxygen Sensor ](#yosemitech-y504-dissolved-oxygen-sensor-) + - [Yosemitech Y510 Turbidity Sensor ](#yosemitech-y510-turbidity-sensor-) + - [Yosemitech Y511 Turbidity Sensor with Wiper ](#yosemitech-y511-turbidity-sensor-with-wiper-) + - [Yosemitech Y514 Chlorophyll Sensor ](#yosemitech-y514-chlorophyll-sensor-) + - [Yosemitech Y520 Conductivity Sensor ](#yosemitech-y520-conductivity-sensor-) + - [Yosemitech Y532 pH Sensor ](#yosemitech-y532-ph-sensor-) + - [Yosemitech Y533 Oxidation Reduction Potential (ORP) Sensor ](#yosemitech-y533-oxidation-reduction-potential-orp-sensor-) + - [Yosemitech Y551 Carbon Oxygen Demand (COD) Sensor with Wiper ](#yosemitech-y551-carbon-oxygen-demand-cod-sensor-with-wiper-) + - [Yosemitech Y560 Ammonium Sensor ](#yosemitech-y560-ammonium-sensor-) + - [Yosemitech Y700 Pressure Sensor ](#yosemitech-y700-pressure-sensor-) + - [Yosemitech Y4000 Multi-Parameter Sonde ](#yosemitech-y4000-multi-parameter-sonde-) + - [Zebra Tech D-Opto Dissolved Oxygen Sensor ](#zebra-tech-d-opto-dissolved-oxygen-sensor-) + - [Calculated Variables ](#calculated-variables-) + - [Creating the array, logger, publishers ](#creating-the-array-logger-publishers-) + - [The variable array ](#the-variable-array-) + - [Creating Variables within an Array ](#creating-variables-within-an-array-) + - [Creating Variables and Pasting UUIDs from MonitorMyWatershed ](#creating-variables-and-pasting-uuids-from-monitormywatershed-) + - [Creating Variables within an Array ](#creating-variables-within-an-array--1) + - [The Logger Object ](#the-logger-object-) + - [Data Publishers ](#data-publishers-) + - [Monitor My Watershed ](#monitor-my-watershed-) + - [DreamHost ](#dreamhost-) + - [ThingSpeak ](#thingspeak-) + - [Ubidots ](#ubidots-) + - [Extra Working Functions ](#extra-working-functions-) + - [Arduino Setup Function ](#arduino-setup-function-) + - [Starting the Function ](#starting-the-function-) + - [Wait for USB ](#wait-for-usb-) + - [Printing a Hello ](#printing-a-hello-) + - [Serial Interrupts ](#serial-interrupts-) + - [Serial Begin ](#serial-begin-) + - [SAMD Pin Peripherals ](#samd-pin-peripherals-) + - [Flash the LEDs ](#flash-the-leds-) + - [Begin the Logger ](#begin-the-logger-) + - [Setup the Sensors ](#setup-the-sensors-) + - [Custom Modem Setup ](#custom-modem-setup-) + - [ESP8266 Baud Rate ](#esp8266-baud-rate-) + - [Skywire Pin Inversions ](#skywire-pin-inversions-) + - [SimCom SIM7080G Network Mode ](#simcom-sim7080g-network-mode-) + - [XBee Cellular Carrier ](#xbee-cellular-carrier-) + - [SARA R4 Cellular Carrier ](#sara-r4-cellular-carrier-) + - [Sync the Real Time Clock ](#sync-the-real-time-clock-) + - [Setup File on the SD card ](#setup-file-on-the-sd-card-) + - [Sleep until the First Data Collection Time ](#sleep-until-the-first-data-collection-time-) + - [Setup Complete ](#setup-complete-) + - [Arduino Loop Function ](#arduino-loop-function-) + - [A Typical Loop ](#a-typical-loop-) + - [A Complex Loop ](#a-complex-loop-) [//]: # ( End GitHub Only ) @@ -806,7 +806,7 @@ ___ -### External Voltage via TI ADS1x15 +### External Voltage via TI ADS1x15 The Arduino pin controlling power on/off and the analog data channel _on the TI ADS1115_ are required for the sensor constructor. If using a voltage divider to increase the measurable voltage range, enter the gain multiplier as the third argument. diff --git a/src/sensors/CampbellRainVUE10.h b/src/sensors/CampbellRainVUE10.h index 1c0042401..41f0c8b45 100644 --- a/src/sensors/CampbellRainVUE10.h +++ b/src/sensors/CampbellRainVUE10.h @@ -112,7 +112,7 @@ * - Accuracy is ±3% at 0 to 300 mm/h intensity (0 to 11.8 in./h intensity) * ±5% at 300 to 500 mm/h intensity (11.8 to 19.7 in./h intensity) * - * {{ @ref CampbellRainVUE10_Preciptation::CampbellRainVUE10_Precipitation }} + * {{ @ref CampbellRainVUE10_Precipitation::CampbellRainVUE10_Precipitation }} */ /**@{*/ /// @brief Decimals places in string representation; depth should have 2 From 9b33edc01534f6c559e9e2acb6028831b45f6cd7 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 16 Mar 2023 11:33:35 -0400 Subject: [PATCH 025/138] Another change to doc build [ci skip] Signed-off-by: Sara Damiano --- .github/workflows/build_documentation.yaml | 2 +- continuous_integration/generate-documentation.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_documentation.yaml b/.github/workflows/build_documentation.yaml index c5d2fdf20..b6b6e61e4 100644 --- a/.github/workflows/build_documentation.yaml +++ b/.github/workflows/build_documentation.yaml @@ -131,7 +131,7 @@ jobs: path: code_docs/m.css - name: Generate all the documentation - continue-on-error: false + continue-on-error: true run: | cd ${{ github.workspace }}/code_docs/ModularSensors/ chmod +x continuous_integration/generate-documentation.sh diff --git a/continuous_integration/generate-documentation.sh b/continuous_integration/generate-documentation.sh index 631b9afda..5985eeaa1 100644 --- a/continuous_integration/generate-documentation.sh +++ b/continuous_integration/generate-documentation.sh @@ -37,7 +37,7 @@ python fixSectionsInXml.py # echo "\n\e[32mFixing copied function documentation in group documentation\e[0m" # python fixFunctionsInGroups.py -python $GITHUB_WORKSPACE/code_docs/m.css/documentation/doxygen.py "mcss-conf.py" --no-doxygen --output "$GITHUB_WORKSPACE/code_docs/ModularSensors/docs/output_mcss.log" --templates "$GITHUB_WORKSPACE/code_docs/m.css/documentation/templates/EnviroDIY" --debug +python $GITHUB_WORKSPACE/code_docs/m.css/documentation/doxygen.py "mcss-conf.py" --no-doxygen --output "$GITHUB_WORKSPACE/code_docs/ModularSensors/docs/output_mcss.log" --templates "$GITHUB_WORKSPACE/code_docs/m.css/documentation/templates/EnviroDIY" echo "\n\e[32mCopying function documentation\e[0m" python copyFunctions.py From 623461c5b161db24c7f7230759777cbb202d12f3 Mon Sep 17 00:00:00 2001 From: Anthony Aufdenkampe Date: Thu, 16 Mar 2023 12:33:32 -0500 Subject: [PATCH 026/138] Add y700 & rainvue to main readme For #433 --- README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 0fb4846f3..798aa5b85 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,14 @@ There is extensive documentation available in the [ModularSensors github pages]( [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) -- [ModularSensors](#modularsensors) - - [The EnviroDIY ModularSensors Library](#the-envirodiy-modularsensors-library) - - [Supported Sensors](#supported-sensors) - - [Data Endpoints](#data-endpoints) - - [Supported Cellular/Wifi Modules:](#supported-cellularwifi-modules) - - [Contributing](#contributing) - - [License](#license) - - [Acknowledgments](#acknowledgments) +- [ModularSensors ](#modularsensors-) + - [The EnviroDIY ModularSensors Library ](#the-envirodiy-modularsensors-library-) + - [Supported Sensors ](#supported-sensors-) + - [Data Endpoints ](#data-endpoints-) + - [Supported Cellular/Wifi Modules: ](#supported-cellularwifi-modules-) + - [Contributing ](#contributing-) + - [License ](#license-) + - [Acknowledgments ](#acknowledgments-) [//]: # ( End GitHub Only ) @@ -58,6 +58,7 @@ For some generalized information about attaching sensors to an Arduino style boa - [Bosch BMP388 and BMP390: barometric pressure & temperature](https://envirodiy.github.io/ModularSensors/group__sensor__bmp3xx.html) - [Campbell Scientific OBS-3+: turbidity, via TI ADS1115](https://envirodiy.github.io/ModularSensors/group__sensor__obs3.html) - [Campbell Scientific ClariVUE10: turbidity](https://envirodiy.github.io/ModularSensors/group__sensor__clarivue.html) +- [Campbell Scientific RainVUE10: precipitation](https://envirodiy.github.io/ModularSensors/group__sensor__rainvue.html) - [Decagon Devices ES-2: conductivity ](https://envirodiy.github.io/ModularSensors/group__sensor__es2.html) - [Decagon Devices CTD-10: conductivity, temperature & depth ](https://envirodiy.github.io/ModularSensors/group__sensor__decagon__ctd.html) - [Everlight ALS-PT19 Analog Light Sensor (via processor ADC)](https://envirodiy.github.io/ModularSensors/group__sensor__alspt19.html) @@ -91,6 +92,7 @@ For some generalized information about attaching sensors to an Arduino style boa - [Y533: ORP, and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y533.html) - [Y551: UV254/COD, Turbidity, and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y551.html) - [Y560: Ammonium, Temperature, and pH](https://envirodiy.github.io/ModularSensors/group__sensor__y560.html) + - [Y700: Pressure and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y700.html) - [Y4000 Multiparameter Sonde](https://envirodiy.github.io/ModularSensors/group__sensor__y4000.html) - [Zebra-Tech D-Opto: dissolved oxygen](https://envirodiy.github.io/ModularSensors/group__sensor__dopto.html) From 9d0b8ae7640ddbc2e7e171a8fd2ecc61540ac8e3 Mon Sep 17 00:00:00 2001 From: Brianna Miller <117111930+brmiller1@users.noreply.github.com> Date: Mon, 7 Nov 2022 16:52:05 -0600 Subject: [PATCH 027/138] add somewhat prototype sensor module for dwyer sblt2 4-20mA sensor --- src/sensors/DwyerSBLT2.cpp | 114 ++++++++++++ src/sensors/DwyerSBLT2.h | 361 +++++++++++++++++++++++++++++++++++++ 2 files changed, 475 insertions(+) create mode 100644 src/sensors/DwyerSBLT2.cpp create mode 100644 src/sensors/DwyerSBLT2.h diff --git a/src/sensors/DwyerSBLT2.cpp b/src/sensors/DwyerSBLT2.cpp new file mode 100644 index 000000000..0c3a040fe --- /dev/null +++ b/src/sensors/DwyerSBLT2.cpp @@ -0,0 +1,114 @@ +/** + * @file CampbellOBS3.cpp + * @copyright 2017-2022 Stroud Water Research Center + * Part of the EnviroDIY ModularSensors library for Arduino + * @author Sara Geleskie Damiano + * + * @brief Implements the CampbellOBS3 class. + */ + + +#include "DwyerSBLT2.h" +#include + + +// The constructor - need the power pin, the data pin, and the calibration info +DwyerSBLT2::DwyerSBLT2(int8_t powerPin, uint8_t adsChannel, float conversion_coefficient, float conversion_constant, + uint8_t i2cAddress, uint8_t measurementsToAverage) + : Sensor("DwyerSBLT2", SBLT2_NUM_VARIABLES, SBLT2_WARM_UP_TIME_MS, + SBLT2_STABILIZATION_TIME_MS, SBLT2_MEASUREMENT_TIME_MS, powerPin, -1, + measurementsToAverage, SBLT2_INC_CALC_VARIABLES), + _adsChannel(adsChannel), + _conversion_coefficient(conversion_coefficient), + _conversion_constant(conversion_constant), + _i2cAddress(i2cAddress) {} +// Destructor +DwyerSBLT2::~DwyerSBLT2() {} + + +String DwyerSBLT2::getSensorLocation(void) { +#ifndef MS_USE_ADS1015 + String sensorLocation = F("ADS1115_0x"); +#else + String sensorLocation = F("ADS1015_0x"); +#endif + sensorLocation += String(_i2cAddress, HEX); + sensorLocation += F("_Channel"); + sensorLocation += String(_adsChannel); + return sensorLocation; +} + +bool DwyerSBLT2::addSingleMeasurementResult(void) { + // Variables to store the results in + float adcVoltage = -9999; + float calibResult = -9999; + + // Check a measurement was *successfully* started (status bit 6 set) + // Only go on to get a result if it was + if (bitRead(_sensorStatus, 6)) { + MS_DBG(getSensorNameAndLocation(), F("is reporting:")); + +// Create an Auxillary ADD object +// We create and set up the ADC object here so that each sensor using +// the ADC may set the gain appropriately without effecting others. +#ifndef MS_USE_ADS1015 + Adafruit_ADS1115 ads(_i2cAddress); // Use this for the 16-bit version +#else + Adafruit_ADS1015 ads(_i2cAddress); // Use this for the 12-bit version +#endif + // ADS Library default settings: + // - TI1115 (16 bit) + // - single-shot mode (powers down between conversions) + // - 128 samples per second (8ms conversion time) + // - 2/3 gain +/- 6.144V range (limited to VDD +0.3V max) + // - TI1015 (12 bit) + // - single-shot mode (powers down between conversions) + // - 1600 samples per second (625µs conversion time) + // - 2/3 gain +/- 6.144V range (limited to VDD +0.3V max) + + // Bump the gain up to 1x = +/- 4.096V range + // Sensor return range is 0-2.5V, but the next gain option is 2x which + // only allows up to 2.048V + ads.setGain(GAIN_ONE); + // Begin ADC + ads.begin(); + + // Print out the calibration curve + MS_DBG(F(" Input calibration Curve:"), _conversion_coefficient, F("x +"), _conversion_constant); + + // Read Analog to Digital Converter (ADC) + // Taking this reading includes the 8ms conversion delay. + // We're allowing the ADS1115 library to do the bit-to-volts conversion + // for us + adcVoltage = + ads.readADC_SingleEnded_V(_adsChannel); // Getting the reading + MS_DBG(F(" ads.readADC_SingleEnded_V("), _adsChannel, F("):"), + adcVoltage); + + if (adcVoltage < 5.0 && adcVoltage > -0.3) { + // Skip results out of range + // Apply the unique calibration curve for the given sensor + calibResult = ((_conversion_coefficient * adcVoltage) - _conversion_constant)/1000; + MS_DBG(F(" calibResult:"), calibResult); + } else { // set invalid voltages back to -9999 + adcVoltage = -9999; + + } + } else { + MS_DBG(getSensorNameAndLocation(), F("is not currently measuring!")); + } + + verifyAndAddMeasurementResult(SBLT2_DEPTH_VAR_NUM, calibResult); + verifyAndAddMeasurementResult(SBLT2_VOLTAGE_VAR_NUM, adcVoltage); + + // Unset the time stamp for the beginning of this measurement + _millisMeasurementRequested = 0; + // Unset the status bits for a measurement request (bits 5 & 6) + _sensorStatus &= 0b10011111; + + if (adcVoltage < 5 && adcVoltage > -0.3) { + return true; + } else { + return false; + } +} diff --git a/src/sensors/DwyerSBLT2.h b/src/sensors/DwyerSBLT2.h new file mode 100644 index 000000000..1547e9550 --- /dev/null +++ b/src/sensors/DwyerSBLT2.h @@ -0,0 +1,361 @@ +/** + * @file DwyerSBLT2.h + * @copyright 2017-2022 Stroud Water Research Center + * Part of the EnviroDIY ModularSensors library for Arduino + * @author Sara Geleskie Damiano + * + * @brief Contains the CampbellOBS3 sensor subclass and the variable subclasses + * CampbellOBS3_Turbidity and CampbellOBS3_Voltage. + * + * These are used for the Campbell Scientific OBS-3+. + * + * This depends on the soligen2010 fork of the Adafruit ADS1015 library. + */ +/* clang-format off */ +/** + * @defgroup sensor_obs3 Campbell OBS3+ + * Classes for the Campbell OBS3+ analog turbidity sensor. + * + * @ingroup analog_group + * + * @tableofcontents + * @m_footernavigation + * + * @section sensor_obs3_intro Introduction + * + * @warning This sensor is no longer manufactured. + * + * The OBS-3+ puts out a simple analog signal between 0 and 2.5V. When the + * sensor is purchased, included in the packaging is a calibration certificate + * to use to convert the voltage into turbidity. + * + * @note The 5V and 4-20mA versions of the OBS3+ are _not_ supported by this + * library. + * + * The OBS3+ supports two different turbidity ranges. The low and high range + * signals are read independently of each other - the signals are on different + * wires. Each range has a separate calibrations. + * + * Before applying any turbidity calibration, the analog output from the OBS3+ + * must be converted into a high resolution digital signal. See the + * [ADS1115 page](@ref analog_group) for details on the conversion. + * + * @section sensor_obs3_datasheet Sensor Datasheet + * - [Basic Concepts](https://github.com/EnviroDIY/ModularSensors/wiki/Sensor-Datasheets/Campbell-OBS3-Basics.pdf) + * - [Manual](https://github.com/EnviroDIY/ModularSensors/wiki/Sensor-Datasheets/Campbell-OBS3-Manual.pdf) + * + * @note Low and high range are treated as completely independent, so only 2 + * "variables" are measured by each sensor - one for the raw voltage and another + * for the calibrated turbidity. To get both high and low range values, create + * two sensor objects! + * + * @section sensor_obs3_flags Build flags + * - ```-D MS_USE_ADS1015``` + * - switches from the 16-bit ADS1115 to the 12 bit ADS1015 + * + * @section sensor_obs3_ctor Sensor Constructor + * {{ @ref CampbellOBS3::CampbellOBS3 }} + * + * ___ + * @section sensor_obs3_examples Example Code + * The Campbell OBS3+ is used in the @menulink{campbell_obs3} example. + * + * @menusnip{campbell_obs3} + */ +/* clang-format on */ + +// Header Guards +#ifndef SRC_SENSORS_DWYERSBLT2_H_ +#define SRC_SENSORS_DWYERSBLT2_H_ + +// Debugging Statement +// #define MS_CAMPBELLOBS3_DEBUG + +#ifdef MS_DWYERSBLT2_DEBUG +#define MS_DEBUGGING_STD "DWYERSBLT2" +#endif + +// Included Dependencies +#include "ModSensorDebugger.h" +#undef MS_DEBUGGING_STD +#include "VariableBase.h" +#include "SensorBase.h" + +// Sensor Specific Defines +/** @ingroup sensor_obs3 */ +/**@{*/ +/** + * @brief Sensor::_numReturnedValues; the SBLT2 will return raw voltage which will be converted into depth(m). + */ +#define SBLT2_NUM_VARIABLES 2 +/// @brief Sensor::_incCalcValues; depth is calculated from raw voltage +/// using the input calibration equation. +#define SBLT2_INC_CALC_VARIABLES 1 + +/** + * @anchor sensor_obs3_timing + * @name Sensor Timing + * The sensor timing for an OBS3+ + */ +/**@{*/ +/// @brief Sensor::_warmUpTime_ms; the ADS1115 warms up in 2ms. +#define SBLT2_WARM_UP_TIME_MS 2 +/// @brief Sensor::_stabilizationTime_ms; minimum stabilization time for the +/// OBS3 is 2s (2000ms). +#define SBLT2_STABILIZATION_TIME_MS 2000 +/// @brief Sensor::_measurementTime_ms; OBS3 takes 100ms to complete a +/// measurement - Maximum data rate = 10Hz (100ms/sample). +///#FIXME look to update to 50ms which is SLTB2 reported response time +#define SBLT2_MEASUREMENT_TIME_MS 100 +/**@}*/ + +/** + * @anchor sensor_obs3_turbidity + * @name Turbidity + * The turbidity variable from an OBS3+ + * - Range: (depends on sediment size, particle shape, and reflectivity) + * - Turbidity (low/high): + * - T1: 250/1000 NTU + * - T2: 500/2000 NTU + * - T3: 1000/4000 NTU + * - Mud: 5000 to 10,000 mg L–1 + * - Sand: 50,000 to 100,000 mg L–1 + * - Accuracy: (whichever is larger) + * - Turbidity: 2% of reading or 0.5 NTU + * - Mud: 2% of reading or 1 mg L–1 + * - Sand: 4% of reading or 10 mg L–1 + * - Resolution: + * - 16-bit ADC, Turbidity: + * - T1: 0.03125/0.125 NTU + * - T2: 0.0625/0.25 NTU + * - T3: 0.125/0.5 NTU + * - @m_span{m-dim}@ref #OBS3_RESOLUTION = 5@m_endspan + * - 12-bit ADC, Turbidity: + * - T1: 0.5/2.0 NTU + * - T2: 1.0/4.0 NTU + * - T3: 2.0/8.0 NTU + * - @m_span{m-dim}@ref #OBS3_RESOLUTION = 1@m_endspan + * + * {{ @ref CampbellOBS3_Turbidity::CampbellOBS3_Turbidity }} + */ +/**@{*/ +/// Variable number; depth is stored in sensorValues[0]. +#define SBLT2_DEPTH_VAR_NUM 0 +#ifdef MS_USE_ADS1015 +/// @brief Decimals places in string representation; depth should have 1. +#define SBLT2_RESOLUTION 1 +#else +/// @brief Decimals places in string representation; depth should have 5. +#define SBLT2_RESOLUTION 5 +#endif +/// @brief Variable name in +/// [ODM2 controlled vocabulary](http://vocabulary.odm2.org/variablename/); +/// "turbidity" +#define SBLT2_DEPTH_VAR_NAME "Depth" +/// @brief Variable unit name in +/// [ODM2 controlled vocabulary](http://vocabulary.odm2.org/units/); +/// "nephelometricTurbidityUnit" (NTU) +#define SBLT2_DEPTH_UNIT_NAME "Meter" +/// @brief Default variable short code; "OBS3Turbidity" +#define SBLT2_DEPTH_DEFAULT_CODE "SBLT2Depth" +/**@}*/ + +/** + * @anchor sensor_obs3_voltage + * @name Voltage + * The voltage variable from an OBS3+ + * - Range is 0 to 2.5V + * - Accuracy: + * - 16-bit ADC (ADS1115): < 0.25% (gain error), < 0.25 LSB (offset errror) + * - @m_span{m-dim}@ref #OBS3_VOLTAGE_RESOLUTION = 4@m_endspan + * - 12-bit ADC (ADS1015, using build flag ```MS_USE_ADS1015```): < 0.15% + * (gain error), < 3 LSB (offset errror) + * - @m_span{m-dim}@ref #OBS3_VOLTAGE_RESOLUTION = 1@m_endspan + * + * {{ @ref CampbellOBS3_Voltage::CampbellOBS3_Voltage }} + */ +/**@{*/ +/// Variable number; voltage is stored in sensorValues[1]. +#define SBLT2_VOLTAGE_VAR_NUM 1 +/// @brief Variable name in +/// [ODM2 controlled vocabulary](http://vocabulary.odm2.org/variablename/); +/// "voltage" +#define SBLT2_VOLTAGE_VAR_NAME "voltage" +/// @brief Variable unit name in +/// [ODM2 controlled vocabulary](http://vocabulary.odm2.org/units/); "volt" +#define SBLT2_VOLTAGE_UNIT_NAME "volt" +/// @brief Default variable short code; "OBS3Voltage" +#define SBLT2_VOLTAGE_DEFAULT_CODE "SBLT2Voltage" + +#ifdef MS_USE_ADS1015 +/// @brief Decimals places in string representation; voltage should have 1. +/// - Resolution: +/// - 16-bit ADC (ADS1115): 0.125 mV +#define SBLT2_VOLTAGE_RESOLUTION 1 +#else +/// @brief Decimals places in string representation; voltage should have 4. +/// - Resolution: +/// - 12-bit ADC (ADS1015, using build flag ```MS_USE_ADS1015```): 2 mV +#define SBLT2_VOLTAGE_RESOLUTION 4 +#endif +/**@}*/ + +/// @brief The assumed address of the ADS1115, 1001 000 (ADDR = GND) +#define ADS1115_ADDRESS 0x48 + +/* clang-format off */ +/** + * @brief The Sensor sub-class for the + * [Campbell OBS3 analog turbidity sensor](@ref sensor_obs3). + * + * Low and high range are treated as completely independent, so only 2 + * "variables" are measured by each sensor - one for the raw voltage and another + * for the calibrated turbidity. To get both high and low range values, create + * two sensor objects! + * + * @ingroup sensor_obs3 + */ +/* clang-format on */ +class DwyerSBLT2 : public Sensor { + public: + // The constructor - need the power pin, the ADS1X15 data channel, and the + // calibration info + /** + * @brief Construct a new Campbell OBS3 object - need the power pin, the + * ADS1X15 data channel, and the calibration info. + * + * @note ModularSensors only supports connecting the ADS1x15 to the primary + * hardware I2C instance defined in the Arduino core. Connecting the ADS to + * a secondary hardware or software I2C instance is *not* supported! + * + * @param powerPin The pin on the mcu controlling power to the OBS3+ + * Use -1 if it is continuously powered. + * - The ADS1x15 requires an input voltage of 2.0-5.5V, but this library + * assumes the ADS is powered with 3.3V. + * - The OBS-3 itself requires a 5-15V power supply, which can be turned off + * between measurements. + * @param adsChannel The analog data channel _on the TI ADS1115_ that the + * OBS3 is connected to (0-3). + * @param x2_coeff_A The x2 (A) coefficient for the calibration _in volts_ + * @param x1_coeff_B The x (B) coefficient for the calibration _in volts_ + * @param x0_coeff_C The x0 (C) coefficient for the calibration _in volts_ + * @param i2cAddress The I2C address of the ADS 1x15, default is 0x48 (ADDR + * = GND) + * @param measurementsToAverage The number of measurements to take and + * average before giving a "final" result from the sensor; optional with a + * default value of 1. + */ + DwyerSBLT2(int8_t powerPin, uint8_t adsChannel, float conversion_coefficient, + float conversion_constant, + uint8_t i2cAddress = ADS1115_ADDRESS, + uint8_t measurementsToAverage = 1); + /** + * @brief Destroy the Dwyer SBLT2 object + */ + ~DwyerSBLT2(); + + /** + * @copydoc Sensor::getSensorLocation() + */ + String getSensorLocation(void) override; + + /** + * @copydoc Sensor::addSingleMeasurementResult() + */ + bool addSingleMeasurementResult(void) override; + + private: + uint8_t _adsChannel; + float _conversion_constant, _conversion_coefficient; + uint8_t _i2cAddress; +}; + + +// The main variable returned is turbidity +// To utilize both high and low gain turbidity, you must create *two* sensor +// objects on two different data channels and then create two variable objects, +// one tied to each sensor. +/* clang-format off */ +/** + * @brief The Variable sub-class used for the + * [turbidity output](@ref sensor_obs3_turbidity) from a [Campbell OBS3+](@ref sensor_obs3). + * + * @ingroup sensor_obs3 + */ +/* clang-format on */ +class DwyerSBLT2_Depth : public Variable { + public: + /** + * @brief Construct a new CampbellOBS3_Turbidity object. + * + * @param parentSense The parent CampbellOBS3 providing the result + * values. + * @param uuid A universally unique identifier (UUID or GUID) for the + * variable; optional with the default value of an empty string. + * @param varCode A short code to help identify the variable in files; + * optional with a default value of "OBS3Turbidity". + */ + explicit DwyerSBLT2_Depth( + DwyerSBLT2* parentSense, const char* uuid = "", + const char* varCode = SBLT2_DEPTH_DEFAULT_CODE) + : Variable(parentSense, (const uint8_t)SBLT2_DEPTH_VAR_NUM, + (uint8_t)SBLT2_RESOLUTION, SBLT2_DEPTH_VAR_NAME, + SBLT2_DEPTH_UNIT_NAME, varCode, uuid) {} + /** + * @brief Construct a new CampbellOBS3_Turbidity object. + * + * @note This must be tied with a parent CampbellOBS3 before it can be used. + */ + DwyerSBLT2_Depth() + : Variable((const uint8_t)SBLT2_DEPTH_VAR_NUM, (uint8_t)SBLT2_RESOLUTION, + SBLT2_DEPTH_VAR_NAME, SBLT2_DEPTH_UNIT_NAME, + SBLT2_DEPTH_DEFAULT_CODE) {} + ~DwyerSBLT2_Depth() {} +}; + + +// Also returning raw voltage +/* clang-format off */ +/** + * @brief The Variable sub-class used for the + * [raw voltage output](@ref sensor_obs3_voltage) from a [Campbell OBS3+](@ref sensor_obs3). + * + * This could be helpful if the calibration equation was typed incorrectly. + * + * @ingroup sensor_obs3 + */ +/* clang-format on */ +class DwyerSBLT2_Voltage : public Variable { + public: + /** + * @brief Construct a new CampbellOBS3_Voltage object. + * + * @param parentSense The parent CampbellOBS3 providing the result + * values. + * @param uuid A universally unique identifier (UUID or GUID) for the + * variable; optional with the default value of an empty string. + * @param varCode A short code to help identify the variable in files; + * optional with a default value of "OBS3Voltage". + */ + explicit DwyerSBLT2_Voltage( + DwyerSBLT2* parentSense, const char* uuid = "", + const char* varCode = SBLT2_VOLTAGE_DEFAULT_CODE) + : Variable(parentSense, (const uint8_t)SBLT2_VOLTAGE_VAR_NUM, + (uint8_t)SBLT2_VOLTAGE_RESOLUTION, SBLT2_VOLTAGE_VAR_NAME, + SBLT2_VOLTAGE_UNIT_NAME, varCode, uuid) {} + /** + * @brief Construct a new CampbellOBS3_Voltage object. + * + * @note This must be tied with a parent CampbellOBS3 before it can be used. + */ + DwyerSBLT2_Voltage() + : Variable((const uint8_t)SBLT2_VOLTAGE_VAR_NUM, + (uint8_t)SBLT2_VOLTAGE_RESOLUTION, SBLT2_VOLTAGE_VAR_NAME, + SBLT2_VOLTAGE_UNIT_NAME, SBLT2_VOLTAGE_DEFAULT_CODE) {} + /** + * @brief Destroy the CampbellOBS3_Voltage object - no action needed. + */ + ~DwyerSBLT2_Voltage() {} +}; +/**@}*/ +#endif // SRC_SENSORS_CAMPBELLOBS3_H_ From 4a71675c664673e2292cb429e6d10a348ed72209 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 17 Nov 2022 12:55:59 -0600 Subject: [PATCH 028/138] reduce sleep power consumption by turning off modem uart properly Saves about 300uA. --- src/LoggerBase.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index b1b49e5be..691ffef1a 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -798,6 +798,20 @@ void Logger::systemSleep(void) { #elif defined ARDUINO_ARCH_AVR + // force bee reset pullup high (not used by SIM7080LTE) + pinMode(A5, OUTPUT); + digitalWrite(A5, HIGH); + + // force UART 1 TX low + pinMode(11, OUTPUT); + digitalWrite(11, LOW); + + // back up old UART configuration + uint8_t uart1_old = UCSR1B; + + // disable UART so they stop setting TX pins high + UCSR1B = 0; + // Set the sleep mode // In the avr/sleep.h file, the call names of these 5 sleep modes are: // SLEEP_MODE_IDLE -the least power savings @@ -883,6 +897,9 @@ void Logger::systemSleep(void) { // Re-enable the processor ADC ADCSRA |= _BV(ADEN); + // restore UART settings + UCSR1B = uart1_old; + // Re-enables interrupts interrupts(); From 3c3ddff53498c96f7463cf55574b29b096472ebe Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 12 Jan 2023 15:32:15 -0600 Subject: [PATCH 029/138] Merge branch 'maxbotix-sensor' Working deployment for surface level --- src/LoggerBase.cpp | 26 ++++++++++++++++---------- src/LoggerBase.h | 6 +++--- src/sensors/MaxBotixSonar.cpp | 11 +++++------ 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 691ffef1a..2ac9af2d6 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -1251,7 +1251,7 @@ void Logger::testingISR() { // This defines what to do in the testing mode -void Logger::testingMode() { +void Logger::testingMode(bool sleepBeforeReturning) { // Flag to notify that we're in testing mode Logger::isTestingNow = true; // Unset the startTesting flag @@ -1336,8 +1336,10 @@ void Logger::testingMode() { // Unset testing mode flag Logger::isTestingNow = false; - // Sleep - systemSleep(); + if (sleepBeforeReturning) { + // Sleep + systemSleep(); + } } @@ -1434,7 +1436,7 @@ void Logger::begin() { // This is a one-and-done to log data -void Logger::logData(void) { +void Logger::logData(bool sleepBeforeReturning) { // Reset the watchdog watchDogTimer.resetWatchDog(); @@ -1478,11 +1480,13 @@ void Logger::logData(void) { // Check if it was instead the testing interrupt that woke us up if (Logger::startTesting) testingMode(); - // Sleep - systemSleep(); + if (sleepBeforeReturning) { + // Sleep + systemSleep(); + } } // This is a one-and-done to log data -void Logger::logDataAndPublish(void) { +void Logger::logDataAndPublish(bool sleepBeforeReturning) { // Reset the watchdog watchDogTimer.resetWatchDog(); @@ -1578,8 +1582,10 @@ void Logger::logDataAndPublish(void) { } // Check if it was instead the testing interrupt that woke us up - if (Logger::startTesting) testingMode(); + if (Logger::startTesting) testingMode(sleepBeforeReturning); - // Call the processor sleep - systemSleep(); + if (sleepBeforeReturning) { + // Sleep + systemSleep(); + } } diff --git a/src/LoggerBase.h b/src/LoggerBase.h index 1cd56e65b..d35528439 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -1103,7 +1103,7 @@ class Logger { * measurements, the sensors are put to sleep, the modem is disconnected * from the internet, and the logger goes back to sleep. */ - virtual void testingMode(); + virtual void testingMode(bool sleepBeforeReturning = true); /**@}*/ // ===================================================================== // @@ -1160,13 +1160,13 @@ class Logger { /** * @brief This is a one-and-done to log data */ - virtual void logData(void); + virtual void logData(bool sleepBeforeReturning = true); /** * @brief This is a one-and-done to log data and publish the results to any * associated publishers. */ - void logDataAndPublish(void); + void logDataAndPublish(bool sleepBeforeReturning = true); /** * @brief The static "marked" epoch time for the local timezone. diff --git a/src/sensors/MaxBotixSonar.cpp b/src/sensors/MaxBotixSonar.cpp index 001d1093d..7c3b1fa62 100644 --- a/src/sensors/MaxBotixSonar.cpp +++ b/src/sensors/MaxBotixSonar.cpp @@ -143,20 +143,19 @@ bool MaxBotixSonar::addSingleMeasurementResult(void) { rangeAttempts++; // If it cannot obtain a result , the sonar is supposed to send a - // value just above it's max range. For 10m models, this is 9999, - // for 5m models it's 4999. The sonar might also send readings of - // 300 or 500 (the blanking distance) if there are too many acoustic - // echos. If the result becomes garbled or the sonar is + // value just above it's max range. For our 7m model, this is 765. + // If the result becomes garbled or the sonar is // disconnected, the parseInt function returns 0. Luckily, these // sensors are not capable of reading 0, so we also know the 0 value // is bad. - if (result <= 300 || result == 500 || result == 4999 || - result == 9999 || result == 0) { + if (result <= 0 || result >= 765) { MS_DBG(F(" Bad or Suspicious Result, Retry Attempt #"), rangeAttempts); result = -9999; } else { MS_DBG(F(" Good result found")); + // convert result from cm to mm + result *= 10; success = true; } } From 998b62d3952fe254333396b2d7140de304fad5b6 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Tue, 24 Jan 2023 12:55:08 -0600 Subject: [PATCH 030/138] change EnviroDIY URL to Memphis server and update copyright For future testing and development --- src/publishers/EnviroDIYPublisher.cpp | 4 +++- src/publishers/EnviroDIYPublisher.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index 5d017ea99..55aab17ec 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -1,8 +1,10 @@ /** * @file EnviroDIYPublisher.cpp * @copyright 2017-2022 Stroud Water Research Center + * @copyright 2023 Thomas Watson * Part of the EnviroDIY ModularSensors library for Arduino * @author Sara Geleskie Damiano + * @author Thomas Watson * * @brief Implements the EnviroDIYPublisher class. */ @@ -18,7 +20,7 @@ // I want to refer to these more than once while ensuring there is only one copy // in memory const char* EnviroDIYPublisher::postEndpoint = "/api/data-stream/"; -const char* EnviroDIYPublisher::enviroDIYHost = "data.envirodiy.org"; +const char* EnviroDIYPublisher::enviroDIYHost = ""; const int EnviroDIYPublisher::enviroDIYPort = 80; const char* EnviroDIYPublisher::tokenHeader = "\r\nTOKEN: "; const char* EnviroDIYPublisher::contentLengthHeader = "\r\nContent-Length: "; diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index 8a728dd1d..6b257a7ee 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -1,8 +1,10 @@ /** * @file EnviroDIYPublisher.h * @copyright 2017-2022 Stroud Water Research Center + * @copyright 2023 Thomas Watson * Part of the EnviroDIY ModularSensors library for Arduino * @author Sara Geleskie Damiano + * @author Thomas Watson * * @brief Contains the EnviroDIYPublisher subclass of dataPublisher for * publishing data to the Monitor My Watershed/EnviroDIY data portal at From 8add74d67a64c11d58727021e26b28a8f17cace2 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 21:08:54 -0600 Subject: [PATCH 031/138] add 8K data buffer for testing Device still reports 3K RAM free --- src/publishers/EnviroDIYPublisher.cpp | 1 + src/publishers/EnviroDIYPublisher.h | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index 55aab17ec..b98c2487a 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -11,6 +11,7 @@ #include "EnviroDIYPublisher.h" +char EnviroDIYPublisher::dataBuffer[MS_DATA_BUFFER_SIZE]; // ============================================================================ // Functions for the EnviroDIY data portal receivers. diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index 6b257a7ee..ad2ab9256 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -18,6 +18,10 @@ // Debugging Statement // #define MS_ENVIRODIYPUBLISHER_DEBUG +#ifndef MS_DATA_BUFFER_SIZE +#define MS_DATA_BUFFER_SIZE 8192 +#endif + #ifdef MS_ENVIRODIYPUBLISHER_DEBUG #define MS_DEBUGGING_STD "EnviroDIYPublisher" #endif @@ -239,6 +243,9 @@ class EnviroDIYPublisher : public dataPublisher { static const char* timestampTag; ///< The JSON feature timestamp tag /**@}*/ + // queued sensor data buffer + static char dataBuffer[MS_DATA_BUFFER_SIZE]; + private: // Tokens and UUID's for EnviroDIY const char* _registrationToken = nullptr; From 9a54111dece24fe202ab6015b2318b37520395af Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 21:11:40 -0600 Subject: [PATCH 032/138] publishers: fix undefined behavior in response code processing Correctly initialize response code variable terminator. --- src/publishers/DreamHostPublisher.cpp | 1 + src/publishers/EnviroDIYPublisher.cpp | 1 + src/publishers/UbidotsPublisher.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/src/publishers/DreamHostPublisher.cpp b/src/publishers/DreamHostPublisher.cpp index fbfa07e7d..f3ae302f7 100644 --- a/src/publishers/DreamHostPublisher.cpp +++ b/src/publishers/DreamHostPublisher.cpp @@ -189,6 +189,7 @@ int16_t DreamHostPublisher::publishData(Client* outClient) { int16_t responseCode = 0; if (did_respond > 0) { char responseCode_char[4]; + responseCode_char[3] = 0; for (uint8_t i = 0; i < 3; i++) { responseCode_char[i] = tempBuffer[i + 9]; } diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index b98c2487a..76763e70b 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -263,6 +263,7 @@ int16_t EnviroDIYPublisher::publishData(Client* outClient) { int16_t responseCode = 0; if (did_respond > 0) { char responseCode_char[4]; + responseCode_char[3] = 0; for (uint8_t i = 0; i < 3; i++) { responseCode_char[i] = tempBuffer[i + 9]; } diff --git a/src/publishers/UbidotsPublisher.cpp b/src/publishers/UbidotsPublisher.cpp index c840cdfcf..afd20a1e7 100644 --- a/src/publishers/UbidotsPublisher.cpp +++ b/src/publishers/UbidotsPublisher.cpp @@ -279,6 +279,7 @@ int16_t UbidotsPublisher::publishData(Client* outClient) { int16_t responseCode = 0; if (did_respond > 0) { char responseCode_char[4]; + responseCode_char[3] = 0; for (uint8_t i = 0; i < 3; i++) { responseCode_char[i] = tempBuffer[i + 9]; } From 590ae1248abf381a4ce737a86186ad31cd0074f2 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Sat, 4 Feb 2023 14:40:37 -0600 Subject: [PATCH 033/138] dataPublisherBase: remove redundant zero init of TX buffer Saves 750 bytes of flash as the buffer can be placed in .bss to be zero-initialized instead of .data. --- src/dataPublisherBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dataPublisherBase.cpp b/src/dataPublisherBase.cpp index 76e298b6c..e21c08285 100644 --- a/src/dataPublisherBase.cpp +++ b/src/dataPublisherBase.cpp @@ -10,7 +10,7 @@ */ #include "dataPublisherBase.h" -char dataPublisher::txBuffer[MS_SEND_BUFFER_SIZE] = {'\0'}; +char dataPublisher::txBuffer[MS_SEND_BUFFER_SIZE]; // Basic chunks of HTTP const char* dataPublisher::getHeader = "GET "; From 47faf5c629e6146eb12513956923728501b92f3a Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 21:18:10 -0600 Subject: [PATCH 034/138] publishers: remove unused functions --- src/publishers/DreamHostPublisher.cpp | 35 ----------------------- src/publishers/DreamHostPublisher.h | 21 -------------- src/publishers/EnviroDIYPublisher.cpp | 40 --------------------------- src/publishers/EnviroDIYPublisher.h | 34 +++-------------------- src/publishers/UbidotsPublisher.cpp | 40 --------------------------- src/publishers/UbidotsPublisher.h | 34 +++-------------------- 6 files changed, 8 insertions(+), 196 deletions(-) diff --git a/src/publishers/DreamHostPublisher.cpp b/src/publishers/DreamHostPublisher.cpp index f3ae302f7..b65c6caed 100644 --- a/src/publishers/DreamHostPublisher.cpp +++ b/src/publishers/DreamHostPublisher.cpp @@ -52,41 +52,6 @@ void DreamHostPublisher::setDreamHostPortalRX(const char* dhUrl) { } -// This prints the URL out to an Arduino stream -void DreamHostPublisher::printSensorDataDreamHost(Stream* stream) { - stream->print(_DreamHostPortalRX); - stream->print(loggerTag); - stream->print(_baseLogger->getLoggerID()); - stream->print(timestampTagDH); - stream->print(String(Logger::markedLocalEpochTime - - 946684800)); // Correct time from epoch to y2k - - for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { - stream->print('&'); - stream->print(_baseLogger->getVarCodeAtI(i)); - stream->print('='); - stream->print(_baseLogger->getValueStringAtI(i)); - } -} - - -// This prints a fully structured GET request for DreamHost to the -// specified stream -void DreamHostPublisher::printDreamHostRequest(Stream* stream) { - // Start the request - stream->print(getHeader); - - // Stream the full URL with parameters - printSensorDataDreamHost(stream); - - // Send the rest of the HTTP header - stream->print(HTTPtag); - stream->print(hostHeader); - stream->print(dreamhostHost); - stream->print(F("\r\n\r\n")); -} - - // A way to begin with everything already set void DreamHostPublisher::begin(Logger& baseLogger, Client* inClient, const char* dhUrl) { diff --git a/src/publishers/DreamHostPublisher.h b/src/publishers/DreamHostPublisher.h index 6a7fe1a46..584be2142 100644 --- a/src/publishers/DreamHostPublisher.h +++ b/src/publishers/DreamHostPublisher.h @@ -133,26 +133,6 @@ class DreamHostPublisher : public dataPublisher { */ void setDreamHostPortalRX(const char* dhUrl); - /** - * @brief This creates all of the URL parameter tags and values and writes - * the result to an Arduino stream. - * - * HTML headers are not included. - * - * @param stream The Arduino stream to write out the URL and parameters to. - */ - void printSensorDataDreamHost(Stream* stream); - - /** - * @brief This prints a fully structured GET request for DreamHost to the - * specified stream. - * - * This includes the HTML headers. - * - * @param stream The Arduino stream to write out the URL and parameters to. - */ - void printDreamHostRequest(Stream* stream); - // A way to begin with everything already set /** * @copydoc dataPublisher::begin(Logger& baseLogger, Client* inClient) @@ -165,7 +145,6 @@ class DreamHostPublisher : public dataPublisher { */ void begin(Logger& baseLogger, const char* dhUrl); - // int16_t postDataDreamHost(void); /** * @brief Utilizes an attached modem to make a TCP connection to the * DreamHost URL and then stream out a get request over that connection. diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index 76763e70b..cb278f592 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -86,45 +86,6 @@ uint16_t EnviroDIYPublisher::calculateJsonSize() { return jsonLength; } -// This prints a properly formatted JSON for EnviroDIY to an Arduino stream -void EnviroDIYPublisher::printSensorDataJSON(Stream* stream) { - stream->print(samplingFeatureTag); - stream->print(_baseLogger->getSamplingFeatureUUID()); - stream->print(timestampTag); - stream->print(Logger::formatDateTime_ISO8601(Logger::markedLocalEpochTime)); - stream->print(F("\",")); - - for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { - stream->print('"'); - stream->print(_baseLogger->getVarUUIDAtI(i)); - stream->print(F("\":")); - stream->print(_baseLogger->getValueStringAtI(i)); - if (i + 1 != _baseLogger->getArrayVarCount()) { stream->print(','); } - } - - stream->print('}'); -} - - -// This prints a fully structured post request for EnviroDIY to the -// specified stream. -void EnviroDIYPublisher::printEnviroDIYRequest(Stream* stream) { - // Stream the HTTP headers for the post request - stream->print(postHeader); - stream->print(postEndpoint); - stream->print(HTTPtag); - stream->print(hostHeader); - stream->print(enviroDIYHost); - stream->print(tokenHeader); - stream->print(_registrationToken); - stream->print(contentLengthHeader); - stream->print(calculateJsonSize()); - stream->print(contentTypeHeader); - - // Stream the JSON itself - printSensorDataJSON(stream); -} - // A way to begin with everything already set void EnviroDIYPublisher::begin(Logger& baseLogger, Client* inClient, @@ -147,7 +108,6 @@ void EnviroDIYPublisher::begin(Logger& baseLogger, // EnviroDIY/ODM2DataSharingPortal and then streams out a post request // over that connection. // The return is the http status code of the response. -// int16_t EnviroDIYPublisher::postDataEnviroDIY(void) int16_t EnviroDIYPublisher::publishData(Client* outClient) { // Create a buffer for the portions of the request and response char tempBuffer[37] = ""; diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index ad2ab9256..c9b74c12e 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -155,30 +155,7 @@ class EnviroDIYPublisher : public dataPublisher { * @return uint16_t The number of characters in the JSON object. */ uint16_t calculateJsonSize(); - // /** - // * @brief Calculates how long the full post request will be, including - // * headers - // * - // * @return uint16_t The length of the full request including HTTP - // headers. - // */ - // uint16_t calculatePostSize(); - /** - * @brief This generates a properly formatted JSON for EnviroDIY and prints - * it to the input Arduino stream object. - * - * @param stream The Arduino stream to write out the JSON to. - */ - void printSensorDataJSON(Stream* stream); - - /** - * @brief This prints a fully structured post request for Monitor My - * Watershed/EnviroDIY to the specified stream. - * - * @param stream The Arduino stream to write out the request to. - */ - void printEnviroDIYRequest(Stream* stream); // A way to begin with everything already set /** @@ -200,7 +177,6 @@ class EnviroDIYPublisher : public dataPublisher { void begin(Logger& baseLogger, const char* registrationToken, const char* samplingFeatureUUID); - // int16_t postDataEnviroDIY(void); /** * @brief Utilize an attached modem to open a a TCP connection to the * EnviroDIY/ODM2DataSharingPortal and then stream out a post request over @@ -223,12 +199,10 @@ class EnviroDIYPublisher : public dataPublisher { * * @{ */ - static const char* postEndpoint; ///< The endpoint - static const char* enviroDIYHost; ///< The host name - static const int enviroDIYPort; ///< The host port - static const char* tokenHeader; ///< The token header text - // static const char *cacheHeader; ///< The cache header text - // static const char *connectionHeader; ///< The keep alive header text + static const char* postEndpoint; ///< The endpoint + static const char* enviroDIYHost; ///< The host name + static const int enviroDIYPort; ///< The host port + static const char* tokenHeader; ///< The token header text static const char* contentLengthHeader; ///< The content length header text static const char* contentTypeHeader; ///< The content type header text /**@}*/ diff --git a/src/publishers/UbidotsPublisher.cpp b/src/publishers/UbidotsPublisher.cpp index afd20a1e7..55f4f5227 100644 --- a/src/publishers/UbidotsPublisher.cpp +++ b/src/publishers/UbidotsPublisher.cpp @@ -93,46 +93,6 @@ uint16_t UbidotsPublisher::calculateJsonSize() { } -// This prints a properly formatted JSON for EnviroDIY to an Arduino stream -void UbidotsPublisher::printSensorDataJSON(Stream* stream) { - stream->print(payload); - - for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { - stream->print('"'); - stream->print(_baseLogger->getVarUUIDAtI(i)); - stream->print(F("\":{'value':")); - stream->print(_baseLogger->getValueStringAtI(i)); - stream->print(",'timestamp':"); - stream->print(Logger::markedUTCEpochTime); - stream->print( - F("000}")); // Convert microseconds to milliseconds for ubidots - if (i + 1 != _baseLogger->getArrayVarCount()) { stream->print(','); } - } - - stream->print(F("}}")); -} - - -// This prints a fully structured post request for Ubidots to the -// specified stream. -void UbidotsPublisher::printUbidotsRequest(Stream* stream) { - // Stream the HTTP headers for the post request - stream->print(postHeader); - stream->print(postEndpoint); - stream->print(HTTPtag); - stream->print(hostHeader); - stream->print(ubidotsHost); - stream->print(tokenHeader); - stream->print(_authentificationToken); - stream->print(contentLengthHeader); - stream->print(calculateJsonSize()); - stream->print(contentTypeHeader); - - // Stream the JSON itself - printSensorDataJSON(stream); -} - - // A way to begin with everything already set void UbidotsPublisher::begin(Logger& baseLogger, Client* inClient, const char* authentificationToken, diff --git a/src/publishers/UbidotsPublisher.h b/src/publishers/UbidotsPublisher.h index adb47f9e2..1562890c6 100644 --- a/src/publishers/UbidotsPublisher.h +++ b/src/publishers/UbidotsPublisher.h @@ -153,30 +153,6 @@ class UbidotsPublisher : public dataPublisher { * @return uint16_t The number of characters in the JSON object. */ uint16_t calculateJsonSize(); - // /** - // * @brief Calculates how long the full post request will be, including - // * headers - // * - // * @return uint16_t The length of the full request including HTTP - // headers. - // */ - // uint16_t calculatePostSize(); - - /** - * @brief This generates a properly formatted JSON for Ubidots and prints - * it to the input Arduino stream object. - * - * @param stream The Arduino stream to write out the JSON to. - */ - void printSensorDataJSON(Stream* stream); - - /** - * @brief This prints a fully structured post request for the Ubidots API - * to the specified stream. - * - * @param stream The Arduino stream to write out the request to. - */ - void printUbidotsRequest(Stream* stream); // A way to begin with everything already set /** @@ -225,12 +201,10 @@ class UbidotsPublisher : public dataPublisher { * * @{ */ - static const char* postEndpoint; ///< The endpoint - static const char* ubidotsHost; ///< The host name - static const int ubidotsPort; ///< The host port - static const char* tokenHeader; ///< The token header text - // static const char *cacheHeader; ///< The cache header text - // static const char *connectionHeader; ///< The keep alive header text + static const char* postEndpoint; ///< The endpoint + static const char* ubidotsHost; ///< The host name + static const int ubidotsPort; ///< The host port + static const char* tokenHeader; ///< The token header text static const char* contentLengthHeader; ///< The content length header text static const char* contentTypeHeader; ///< The content type header text /**@}*/ From 7a827fa13db8f9985e4adcb24bdb965013cc0173 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 21:23:29 -0600 Subject: [PATCH 035/138] publishers: refactor transmit buffer usage Use cleaner interface and common functions that avoid repeated snprintf and strlen usage to save ~2.5KB of flash and dozens of lines of code. Removes extra \r\n from HTTP requests as a side effect, which were against spec and caused spurious 400 Bad Request status messages from servers. --- src/dataPublisherBase.cpp | 52 +++++++++----- src/dataPublisherBase.h | 54 +++++++++----- src/publishers/DreamHostPublisher.cpp | 64 ++++++----------- src/publishers/EnviroDIYPublisher.cpp | 93 ++++++++---------------- src/publishers/ThingSpeakPublisher.cpp | 27 +++---- src/publishers/UbidotsPublisher.cpp | 99 +++++++------------------- 6 files changed, 160 insertions(+), 229 deletions(-) diff --git a/src/dataPublisherBase.cpp b/src/dataPublisherBase.cpp index e21c08285..1ad4a4d17 100644 --- a/src/dataPublisherBase.cpp +++ b/src/dataPublisherBase.cpp @@ -11,6 +11,8 @@ #include "dataPublisherBase.h" char dataPublisher::txBuffer[MS_SEND_BUFFER_SIZE]; +Client* dataPublisher::txBufferOutClient = nullptr; +size_t dataPublisher::txBufferLen; // Basic chunks of HTTP const char* dataPublisher::getHeader = "GET "; @@ -71,34 +73,48 @@ void dataPublisher::begin(Logger& baseLogger) { } -// Empties the outgoing buffer -void dataPublisher::emptyTxBuffer(void) { - MS_DBG(F("Dumping the TX Buffer")); - for (int i = 0; i < MS_SEND_BUFFER_SIZE; i++) { txBuffer[i] = '\0'; } +void dataPublisher::txBufferInit(Client* outClient) { + // remember client we are sending to + txBufferOutClient = outClient; + + // reset buffer length to be empty + txBufferLen = 0; } +void dataPublisher::txBufferAppend(const char* data, size_t length) { + while (length > 0) { + size_t remaining = MS_SEND_BUFFER_SIZE - txBufferLen; + size_t amount = remaining < length ? remaining : length; + + memcpy(&txBuffer[txBufferLen], data, amount); + length -= amount; + data += amount; + txBufferLen += amount; + + if (txBufferLen == MS_SEND_BUFFER_SIZE) { + txBufferFlush(); + } + } +} -// Returns how much space is left in the buffer -int dataPublisher::bufferFree(void) { - MS_DBG(F("Current TX Buffer Size:"), strlen(txBuffer)); - return MS_SEND_BUFFER_SIZE - strlen(txBuffer); +void dataPublisher::txBufferAppend(const char* s) { + txBufferAppend(s, strlen(s)); } +void dataPublisher::txBufferAppend(char c) { + txBufferAppend(&c, 1); +} -// Sends the tx buffer to a stream and then clears it -void dataPublisher::printTxBuffer(Stream* stream, bool addNewLine) { -// Send the out buffer so far to the serial for debugging +void dataPublisher::txBufferFlush() { #if defined(STANDARD_SERIAL_OUTPUT) - STANDARD_SERIAL_OUTPUT.write(txBuffer, strlen(txBuffer)); - if (addNewLine) { PRINTOUT('\n'); } + // send to debugging stream + STANDARD_SERIAL_OUTPUT.write((const uint8_t*)txBuffer, txBufferLen); STANDARD_SERIAL_OUTPUT.flush(); #endif - stream->write(txBuffer, strlen(txBuffer)); - if (addNewLine) { stream->print("\r\n"); } - stream->flush(); + txBufferOutClient->write((const uint8_t*)txBuffer, txBufferLen); + txBufferOutClient->flush(); - // empty the buffer after printing it - emptyTxBuffer(); + txBufferLen = 0; } diff --git a/src/dataPublisherBase.h b/src/dataPublisherBase.h index d43ba5dde..91b4f9060 100644 --- a/src/dataPublisherBase.h +++ b/src/dataPublisherBase.h @@ -32,11 +32,10 @@ * @def MS_SEND_BUFFER_SIZE * @brief Send Buffer * - * This determines how many characters to set out at once over the TCP/UDP - * connection. Increasing this may decrease data use by a loger, while - * decreasing it will save memory. Do not make it smaller than 47 (to keep all - * variable values with their UUID's) or bigger than 1500 (a typical TCP/UDP - * Maximum Transmission Unit). + * This determines how many characters to set out at once over the TCP + * connection. Increasing this may decrease data use by a logger, while + * decreasing it will save memory. Do not make it smaller than 32 or bigger + * than 1500 (a typical TCP Maximum Transmission Unit). * * This can be changed by setting the build flag MS_SEND_BUFFER_SIZE when * compiling. @@ -280,29 +279,48 @@ class dataPublisher { Client* _inClient = nullptr; /** - * @brief A buffer for outgoing data. + * @brief The buffer for outgoing data. */ static char txBuffer[MS_SEND_BUFFER_SIZE]; /** - * @brief Get the number of empty spots in the buffer. + * @brief The pointer to the client instance the TX buffer is writing to. + */ + static Client* txBufferOutClient; + /** + * @brief The number of used characters in the TX buffer. + */ + static size_t txBufferLen; + /** + * @brief Initialize the TX buffer to be empty and start writing to the + * given client. + * + * @param client The client to transmit to. + */ + static void txBufferInit(Client* outClient); + /** + * @brief Append the given data to the TX buffer, flushing if necessary. * - * @return **int** The number of available characters in the buffer + * @param data The data start pointer. + * @param length The number of bytes to add. */ - static int bufferFree(void); + static void txBufferAppend(const char* data, size_t length); /** - * @brief Fill the TX buffer with nulls ('\0'). + * @brief Append the given string to the TX buffer, flushing if necessary. + * + * @param s The null-terminated string to append. */ - static void emptyTxBuffer(void); + static void txBufferAppend(const char* s); /** - * @brief Write the TX buffer to a stream and also to the debugging - * port. + * @brief Append the given char to the TX buffer, flushing if necessary. * - * @param stream A pointer to an Arduino Stream instance to use to print - * data - * @param addNewLine True to add a new line character ("\n") at the end of - * the print + * @param c The char to append. + */ + static void txBufferAppend(char c); + /** + * @brief Write the TX buffer contents to the initialized stream and also to + * the debugging port. */ - static void printTxBuffer(Stream* stream, bool addNewLine = false); + static void txBufferFlush(); /** * @brief Unimplemented; intended for future use to enable caching and bulk diff --git a/src/publishers/DreamHostPublisher.cpp b/src/publishers/DreamHostPublisher.cpp index b65c6caed..5c3db12f6 100644 --- a/src/publishers/DreamHostPublisher.cpp +++ b/src/publishers/DreamHostPublisher.cpp @@ -76,59 +76,41 @@ int16_t DreamHostPublisher::publishData(Client* outClient) { MS_START_DEBUG_TIMER; if (outClient->connect(dreamhostHost, dreamhostPort)) { MS_DBG(F("Client connected after"), MS_PRINT_DEBUG_TIMER, F("ms\n")); + txBufferInit(outClient); // copy the initial post header into the tx buffer - snprintf(txBuffer, sizeof(txBuffer), "%s", getHeader); + txBufferAppend(getHeader); // add in the dreamhost receiver URL - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", _DreamHostPortalRX); + txBufferAppend(_DreamHostPortalRX); // start the URL parameters - if (bufferFree() < 16) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", loggerTag); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", - _baseLogger->getLoggerID()); - - if (bufferFree() < 22) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", timestampTagDH); + txBufferAppend(loggerTag); + txBufferAppend(_baseLogger->getLoggerID()); + + txBufferAppend(timestampTagDH); ltoa((Logger::markedLocalEpochTime - 946684800), tempBuffer, 10); // BASE 10 - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); + txBufferAppend(tempBuffer); for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { - // Once the buffer fills, send it out - if (bufferFree() < 47) printTxBuffer(outClient); - - txBuffer[strlen(txBuffer)] = '&'; - _baseLogger->getVarCodeAtI(i).toCharArray(tempBuffer, 37); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); - txBuffer[strlen(txBuffer)] = '='; - _baseLogger->getValueStringAtI(i).toCharArray(tempBuffer, 37); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); + txBufferAppend('&'); + txBufferAppend(_baseLogger->getVarCodeAtI(i).c_str()); + txBufferAppend('='); + txBufferAppend(_baseLogger->getValueStringAtI(i).c_str()); } // add the rest of the HTTP GET headers to the outgoing buffer - if (bufferFree() < 52) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", HTTPtag); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", hostHeader); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", dreamhostHost); - txBuffer[strlen(txBuffer)] = '\r'; - txBuffer[strlen(txBuffer)] = '\n'; - txBuffer[strlen(txBuffer)] = '\r'; - txBuffer[strlen(txBuffer)] = '\n'; - - // Send out the finished request (or the last unsent section of it) - printTxBuffer(outClient); + txBufferAppend(HTTPtag); + txBufferAppend(hostHeader); + txBufferAppend(dreamhostHost); + txBufferAppend('\r'); + txBufferAppend('\n'); + txBufferAppend('\r'); + txBufferAppend('\n'); + + // Flush the complete request + txBufferFlush(); // Wait 10 seconds for a response from the server uint32_t start = millis(); @@ -163,7 +145,7 @@ int16_t DreamHostPublisher::publishData(Client* outClient) { responseCode = 504; } - PRINTOUT(F("-- Response Code --")); + PRINTOUT(F("\n-- Response Code --")); PRINTOUT(responseCode); return responseCode; diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index cb278f592..a43e1c617 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -120,83 +120,50 @@ int16_t EnviroDIYPublisher::publishData(Client* outClient) { MS_START_DEBUG_TIMER; if (outClient->connect(enviroDIYHost, enviroDIYPort)) { MS_DBG(F("Client connected after"), MS_PRINT_DEBUG_TIMER, F("ms\n")); + txBufferInit(outClient); // copy the initial post header into the tx buffer - snprintf(txBuffer, sizeof(txBuffer), "%s", postHeader); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", postEndpoint); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", HTTPtag); + txBufferAppend(postHeader); + txBufferAppend(postEndpoint); + txBufferAppend(HTTPtag); // add the rest of the HTTP POST headers to the outgoing buffer - // before adding each line/chunk to the outgoing buffer, we make sure - // there is space for that line, sending out buffer if not - if (bufferFree() < 28) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", hostHeader); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", enviroDIYHost); - - if (bufferFree() < 47) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tokenHeader); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", _registrationToken); - - if (bufferFree() < 26) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", - contentLengthHeader); + txBufferAppend(hostHeader); + txBufferAppend(enviroDIYHost); + txBufferAppend(tokenHeader); + txBufferAppend(_registrationToken); + + txBufferAppend(contentLengthHeader); itoa(calculateJsonSize(), tempBuffer, 10); // BASE 10 - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); + txBufferAppend(tempBuffer); - if (bufferFree() < 42) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", contentTypeHeader); + txBufferAppend(contentTypeHeader); // put the start of the JSON into the outgoing response_buffer - if (bufferFree() < 21) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", samplingFeatureTag); - - if (bufferFree() < 36) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", - _baseLogger->getSamplingFeatureUUID()); - - if (bufferFree() < 42) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", timestampTag); - Logger::formatDateTime_ISO8601(Logger::markedLocalEpochTime) - .toCharArray(tempBuffer, 37); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); - txBuffer[strlen(txBuffer)] = '"'; - txBuffer[strlen(txBuffer)] = ','; + txBufferAppend(samplingFeatureTag); + txBufferAppend(_baseLogger->getSamplingFeatureUUID()); + + txBufferAppend(timestampTag); + txBufferAppend(Logger::formatDateTime_ISO8601( + Logger::markedLocalEpochTime).c_str()); + txBufferAppend('"'); + txBufferAppend(','); for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { - // Once the buffer fills, send it out - if (bufferFree() < 47) printTxBuffer(outClient); - - txBuffer[strlen(txBuffer)] = '"'; - _baseLogger->getVarUUIDAtI(i).toCharArray(tempBuffer, 37); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); - txBuffer[strlen(txBuffer)] = '"'; - txBuffer[strlen(txBuffer)] = ':'; - _baseLogger->getValueStringAtI(i).toCharArray(tempBuffer, 37); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); + txBufferAppend('"'); + txBufferAppend(_baseLogger->getVarUUIDAtI(i).c_str()); + txBufferAppend('"'); + txBufferAppend(':'); + txBufferAppend(_baseLogger->getValueStringAtI(i).c_str()); if (i + 1 != _baseLogger->getArrayVarCount()) { - txBuffer[strlen(txBuffer)] = ','; + txBufferAppend(','); } else { - txBuffer[strlen(txBuffer)] = '}'; + txBufferAppend('}'); } } - // Send out the finished request (or the last unsent section of it) - printTxBuffer(outClient, true); + // Flush the complete request + txBufferFlush(); // Wait 10 seconds for a response from the server uint32_t start = millis(); @@ -232,7 +199,7 @@ int16_t EnviroDIYPublisher::publishData(Client* outClient) { responseCode = 504; } - PRINTOUT(F("-- Response Code --")); + PRINTOUT(F("\n-- Response Code --")); PRINTOUT(responseCode); return responseCode; diff --git a/src/publishers/ThingSpeakPublisher.cpp b/src/publishers/ThingSpeakPublisher.cpp index e1b0e3a7f..1a020434e 100644 --- a/src/publishers/ThingSpeakPublisher.cpp +++ b/src/publishers/ThingSpeakPublisher.cpp @@ -129,27 +129,20 @@ int16_t ThingSpeakPublisher::publishData(Client* outClient) { _thingSpeakChannelKey); MS_DBG(F("Topic ["), strlen(topicBuffer), F("]:"), String(topicBuffer)); - emptyTxBuffer(); + // buffer is used only locally, it does not transmit + txBufferInit(nullptr); - Logger::formatDateTime_ISO8601(Logger::markedLocalEpochTime) - .toCharArray(tempBuffer, 26); - snprintf(txBuffer + strlen(txBuffer), sizeof(txBuffer) - strlen(txBuffer), - "%s", "created_at="); - snprintf(txBuffer + strlen(txBuffer), sizeof(txBuffer) - strlen(txBuffer), - "%s", tempBuffer); - txBuffer[strlen(txBuffer)] = '&'; + txBufferAppend(Logger::formatDateTime_ISO8601( + Logger::markedLocalEpochTime).c_str()); + txBufferAppend("created_at="); for (uint8_t i = 0; i < numChannels; i++) { - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", "field"); + txBufferAppend('&'); + txBufferAppend("field"); itoa(i + 1, tempBuffer, 10); // BASE 10 - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); - txBuffer[strlen(txBuffer)] = '='; - _baseLogger->getValueStringAtI(i).toCharArray(tempBuffer, 26); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); - if (i + 1 != numChannels) { txBuffer[strlen(txBuffer)] = '&'; } + txBufferAppend(tempBuffer); + txBufferAppend('='); + txBufferAppend(_baseLogger->getValueStringAtI(i).c_str()); } MS_DBG(F("Message ["), strlen(txBuffer), F("]:"), String(txBuffer)); diff --git a/src/publishers/UbidotsPublisher.cpp b/src/publishers/UbidotsPublisher.cpp index 55f4f5227..c1e781d62 100644 --- a/src/publishers/UbidotsPublisher.cpp +++ b/src/publishers/UbidotsPublisher.cpp @@ -127,93 +127,48 @@ int16_t UbidotsPublisher::publishData(Client* outClient) { MS_START_DEBUG_TIMER; if (outClient->connect(ubidotsHost, ubidotsPort)) { MS_DBG(F("Client connected after"), MS_PRINT_DEBUG_TIMER, F("ms\n")); + txBufferInit(outClient); // copy the initial post header into the tx buffer - snprintf(txBuffer, sizeof(txBuffer), "%s", postHeader); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", postEndpoint); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", - _baseLogger->getSamplingFeatureUUID()); - txBuffer[strlen(txBuffer)] = '/'; - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", HTTPtag); + txBufferAppend(postHeader); + txBufferAppend(postEndpoint); + txBufferAppend(_baseLogger->getSamplingFeatureUUID()); + txBufferAppend('/'); + txBufferAppend(HTTPtag); // add the rest of the HTTP POST headers to the outgoing buffer - // before adding each line/chunk to the outgoing buffer, we make sure - // there is space for that line, sending out buffer if not - if (bufferFree() < 28) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", hostHeader); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", ubidotsHost); - - if (bufferFree() < 47) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tokenHeader); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", - _authentificationToken); - - if (bufferFree() < 26) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", - contentLengthHeader); + txBufferAppend(hostHeader); + txBufferAppend(ubidotsHost); + txBufferAppend(tokenHeader); + txBufferAppend(_authentificationToken); + + txBufferAppend(contentLengthHeader); itoa(calculateJsonSize(), tempBuffer, 10); // BASE 10 - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); + txBufferAppend(tempBuffer); - if (bufferFree() < 42) printTxBuffer(outClient); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", contentTypeHeader); + txBufferAppend(contentTypeHeader); // put the start of the JSON into the outgoing response_buffer - if (bufferFree() < 21) printTxBuffer(outClient); - - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", payload); + txBufferAppend(payload); for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { - // Once the buffer fills, send it out - if (bufferFree() < 47) printTxBuffer(outClient); - - txBuffer[strlen(txBuffer)] = '"'; - _baseLogger->getVarUUIDAtI(i).toCharArray(tempBuffer, 37); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); - txBuffer[strlen(txBuffer)] = '"'; - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", ":{"); - txBuffer[strlen(txBuffer)] = '"'; - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", "value"); - txBuffer[strlen(txBuffer)] = '"'; - txBuffer[strlen(txBuffer)] = ':'; - _baseLogger->getValueStringAtI(i).toCharArray(tempBuffer, 37); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); - txBuffer[strlen(txBuffer)] = ','; - txBuffer[strlen(txBuffer)] = '"'; - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", "timestamp"); - txBuffer[strlen(txBuffer)] = '"'; - txBuffer[strlen(txBuffer)] = ':'; + txBufferAppend('"'); + txBufferAppend(_baseLogger->getVarUUIDAtI(i).c_str()); + txBufferAppend("\":{\"value\":"); + txBufferAppend(_baseLogger->getValueStringAtI(i).c_str()); + txBufferAppend(",\"timestamp\":"); ltoa(Logger::markedUTCEpochTime, tempBuffer, 10); // BASE 10 - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", tempBuffer); - snprintf(txBuffer + strlen(txBuffer), - sizeof(txBuffer) - strlen(txBuffer), "%s", "000"); + txBufferAppend(tempBuffer); + txBufferAppend("000}"); if (i + 1 != _baseLogger->getArrayVarCount()) { - txBuffer[strlen(txBuffer)] = '}'; - txBuffer[strlen(txBuffer)] = ','; + txBufferAppend(','); } else { - txBuffer[strlen(txBuffer)] = '}'; - txBuffer[strlen(txBuffer)] = '}'; + txBufferAppend('}'); } } - // Send out the finished request (or the last unsent section of it) - printTxBuffer(outClient, true); + // Flush the complete request + txBufferFlush(); // Wait 10 seconds for a response from the server uint32_t start = millis(); @@ -248,7 +203,7 @@ int16_t UbidotsPublisher::publishData(Client* outClient) { responseCode = 504; } - PRINTOUT(F("-- Response Code --")); + PRINTOUT(F("\n-- Response Code --")); PRINTOUT(responseCode); return responseCode; From c05cfd6c734b947a134a8bea4945a3da07de7d46 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 21:30:59 -0600 Subject: [PATCH 036/138] publishers/EnviroDIYPublisher: send data as one element arrays For testing the server component --- src/publishers/EnviroDIYPublisher.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index a43e1c617..0f2bbbb0b 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -29,7 +29,7 @@ const char* EnviroDIYPublisher::contentTypeHeader = "\r\nContent-Type: application/json\r\n\r\n"; const char* EnviroDIYPublisher::samplingFeatureTag = "{\"sampling_feature\":\""; -const char* EnviroDIYPublisher::timestampTag = "\",\"timestamp\":\""; +const char* EnviroDIYPublisher::timestampTag = "\",\"timestamp\":[\""; // Constructors @@ -69,13 +69,13 @@ void EnviroDIYPublisher::setToken(const char* registrationToken) { uint16_t EnviroDIYPublisher::calculateJsonSize() { uint16_t jsonLength = 21; // {"sampling_feature":" jsonLength += 36; // sampling feature UUID - jsonLength += 15; // ","timestamp":" + jsonLength += 17; // ","timestamp":["] jsonLength += 25; // markedISO8601Time jsonLength += 2; // ", for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { jsonLength += 1; // " jsonLength += 36; // variable UUID - jsonLength += 2; // ": + jsonLength += 4; // ":[] jsonLength += _baseLogger->getValueStringAtI(i).length(); if (i + 1 != _baseLogger->getArrayVarCount()) { jsonLength += 1; // , @@ -147,6 +147,7 @@ int16_t EnviroDIYPublisher::publishData(Client* outClient) { txBufferAppend(Logger::formatDateTime_ISO8601( Logger::markedLocalEpochTime).c_str()); txBufferAppend('"'); + txBufferAppend(']'); txBufferAppend(','); for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { @@ -154,7 +155,9 @@ int16_t EnviroDIYPublisher::publishData(Client* outClient) { txBufferAppend(_baseLogger->getVarUUIDAtI(i).c_str()); txBufferAppend('"'); txBufferAppend(':'); + txBufferAppend('['); txBufferAppend(_baseLogger->getValueStringAtI(i).c_str()); + txBufferAppend(']'); if (i + 1 != _baseLogger->getArrayVarCount()) { txBufferAppend(','); } else { From 793bbb93713af466cfcf34e8a5416172de64277c Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 21:37:15 -0600 Subject: [PATCH 037/138] publishers/EnviroDIYPublisher: buffer log data and send in batches Serialize timestamps and variable values to the data buffer, then unserialize and format into JSON arrays. Offers considerable data and power savings. --- src/LoggerBase.cpp | 9 +++ src/LoggerBase.h | 18 +++++ src/VariableBase.cpp | 11 ++- src/VariableBase.h | 8 ++ src/publishers/EnviroDIYPublisher.cpp | 102 +++++++++++++++++++++++--- src/publishers/EnviroDIYPublisher.h | 5 ++ 6 files changed, 140 insertions(+), 13 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 2ac9af2d6..7cc09cce4 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -266,11 +266,20 @@ String Logger::getVarCodeAtI(uint8_t position_i) { String Logger::getVarUUIDAtI(uint8_t position_i) { return _internalArray->arrayOfVars[position_i]->getVarUUID(); } +// This returns the current value of the variable as a float +float Logger::getValueAtI(uint8_t position_i) { + return _internalArray->arrayOfVars[position_i]->getValue(); +} // This returns the current value of the variable as a string with the // correct number of significant figures String Logger::getValueStringAtI(uint8_t position_i) { return _internalArray->arrayOfVars[position_i]->getValueString(); } +// This returns a particular value of the variable as a string with the +// correct number of significant figures +String Logger::formatValueStringAtI(uint8_t position_i, float value) { + return _internalArray->arrayOfVars[position_i]->formatValueString(value); +} // ===================================================================== // diff --git a/src/LoggerBase.h b/src/LoggerBase.h index d35528439..21cafb22e 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -509,6 +509,14 @@ class Logger { * @return **String** The variable UUID */ String getVarUUIDAtI(uint8_t position_i); + /** + * @brief Get the most recent value of the variable at the given position in + * the internal variable array object. + * + * @param position_i The position of the variable in the array. + * @return **float** The value of the variable as a float. + */ + float getValueAtI(uint8_t position_i); /** * @brief Get the most recent value of the variable at the given position in * the internal variable array object. @@ -518,6 +526,16 @@ class Logger { * number of significant figures. */ String getValueStringAtI(uint8_t position_i); + /** + * @brief Get the string representing a particular value of the variable at + * the given position in the internal variable array object. + * + * @param position_i The position of the variable in the array. + * @param value The value to format. + * @return **String** The given value as a string with the correct number of + * significant figures. + */ + String formatValueStringAtI(uint8_t position_i, float value); protected: /** diff --git a/src/VariableBase.cpp b/src/VariableBase.cpp index 16cc3f10f..1c3290b33 100644 --- a/src/VariableBase.cpp +++ b/src/VariableBase.cpp @@ -253,11 +253,18 @@ float Variable::getValue(bool updateValue) { // This returns the current value of the variable as a string // with the correct number of significant figures String Variable::getValueString(bool updateValue) { + return formatValueString(getValue(updateValue)); +} + + +// This returns a particular value of the variable as a string +// with the correct number of significant figures +String Variable::formatValueString(float value) { // Need this because otherwise get extra spaces in strings from int if (_decimalResolution == 0) { - auto val = static_cast(getValue(updateValue)); + auto val = static_cast(value); return String(val); } else { - return String(getValue(updateValue), _decimalResolution); + return String(value, _decimalResolution); } } diff --git a/src/VariableBase.h b/src/VariableBase.h index 83b1c007e..13bfb1095 100644 --- a/src/VariableBase.h +++ b/src/VariableBase.h @@ -355,6 +355,14 @@ class Variable { * @return **String** The current value of the variable */ String getValueString(bool updateValue = false); + /** + * @brief Get a particular value of the variable as a string with the + * correct decimal resolution + * + * @param value value to format + * @return **String** The formatted value of the variable + */ + String formatValueString(float value); /** * @brief Pointer to the parent sensor diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index 0f2bbbb0b..3b812ce3d 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -12,6 +12,7 @@ #include "EnviroDIYPublisher.h" char EnviroDIYPublisher::dataBuffer[MS_DATA_BUFFER_SIZE]; +int EnviroDIYPublisher::dataBufferNumRecords; // ============================================================================ // Functions for the EnviroDIY data portal receivers. @@ -29,7 +30,7 @@ const char* EnviroDIYPublisher::contentTypeHeader = "\r\nContent-Type: application/json\r\n\r\n"; const char* EnviroDIYPublisher::samplingFeatureTag = "{\"sampling_feature\":\""; -const char* EnviroDIYPublisher::timestampTag = "\",\"timestamp\":[\""; +const char* EnviroDIYPublisher::timestampTag = "\",\"timestamp\":["; // Constructors @@ -67,16 +68,34 @@ void EnviroDIYPublisher::setToken(const char* registrationToken) { // Calculates how long the JSON will be uint16_t EnviroDIYPublisher::calculateJsonSize() { - uint16_t jsonLength = 21; // {"sampling_feature":" - jsonLength += 36; // sampling feature UUID - jsonLength += 17; // ","timestamp":["] - jsonLength += 25; // markedISO8601Time - jsonLength += 2; // ", + char* ptr = (char*)&dataBuffer; + size_t recordSize = + sizeof(uint32_t)+sizeof(float)*_baseLogger->getArrayVarCount(); + + uint16_t jsonLength = strlen(samplingFeatureTag); + jsonLength += 36; // sampling feature UUID + jsonLength += strlen(timestampTag); + // markedISO8601Time + quotes and commas + jsonLength += dataBufferNumRecords * (25 + 2) + dataBufferNumRecords - 1; + jsonLength += 2; // ], for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { jsonLength += 1; // " jsonLength += 36; // variable UUID jsonLength += 4; // ":[] - jsonLength += _baseLogger->getValueStringAtI(i).length(); + + ptr = (char*)&dataBuffer; + ptr += sizeof(uint32_t); // skip timestamp + ptr += i*sizeof(float); // and previous variables + for (int j = 0; j < dataBufferNumRecords; j++) { + float value; + memcpy((void*)&value, ptr, sizeof(float)); + ptr += recordSize; + + jsonLength += _baseLogger->formatValueStringAtI(i, value).length(); + if (j + 1 != dataBufferNumRecords) { + jsonLength += 1; // , + } + } if (i + 1 != _baseLogger->getArrayVarCount()) { jsonLength += 1; // , } @@ -109,6 +128,32 @@ void EnviroDIYPublisher::begin(Logger& baseLogger, // over that connection. // The return is the http status code of the response. int16_t EnviroDIYPublisher::publishData(Client* outClient) { + // record timestamp and variable values into the data buffer + + // compute where we will record to + size_t recordSize = + sizeof(uint32_t)+sizeof(float)*_baseLogger->getArrayVarCount(); + char* ptr = &dataBuffer[recordSize*dataBufferNumRecords]; + + memcpy(ptr, (void*)&Logger::markedLocalEpochTime, sizeof(uint32_t)); + ptr += sizeof(uint32_t); + + for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { + float value = _baseLogger->getValueAtI(i); + memcpy(ptr, (void*)&value, sizeof(float)); + ptr += sizeof(float); + } + + dataBufferNumRecords += 1; + + if (dataBufferNumRecords == 2) { + return flushDataBuffer(outClient); + } + + return 201; // pretend everything went okay? +} + +int16_t EnviroDIYPublisher::flushDataBuffer(Client* outClient) { // Create a buffer for the portions of the request and response char tempBuffer[37] = ""; uint16_t did_respond = 0; @@ -144,20 +189,50 @@ int16_t EnviroDIYPublisher::publishData(Client* outClient) { txBufferAppend(_baseLogger->getSamplingFeatureUUID()); txBufferAppend(timestampTag); - txBufferAppend(Logger::formatDateTime_ISO8601( - Logger::markedLocalEpochTime).c_str()); - txBufferAppend('"'); + + // write out list of timestamps + char* ptr = (char*)&dataBuffer; + size_t recordSize = + sizeof(uint32_t)+sizeof(float)*_baseLogger->getArrayVarCount(); + for (int i = 0; i < dataBufferNumRecords; i++) { + uint32_t value; + memcpy((void*)&value, ptr, sizeof(uint32_t)); + ptr += recordSize; + + txBufferAppend('"'); + txBufferAppend(Logger::formatDateTime_ISO8601(value).c_str()); + txBufferAppend('"'); + if (i + 1 != dataBufferNumRecords) { + txBufferAppend(','); + } + } txBufferAppend(']'); txBufferAppend(','); + // write out a list of the values of each variable for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { txBufferAppend('"'); txBufferAppend(_baseLogger->getVarUUIDAtI(i).c_str()); txBufferAppend('"'); txBufferAppend(':'); txBufferAppend('['); - txBufferAppend(_baseLogger->getValueStringAtI(i).c_str()); + + ptr = (char*)&dataBuffer; + ptr += sizeof(uint32_t); // skip timestamp + ptr += i*sizeof(float); // and previous variables + for (int j = 0; j < dataBufferNumRecords; j++) { + float value; + memcpy((void*)&value, ptr, sizeof(float)); + ptr += recordSize; + + txBufferAppend( + _baseLogger->formatValueStringAtI(i, value).c_str()); + if (j + 1 != dataBufferNumRecords) { + txBufferAppend(','); + } + } txBufferAppend(']'); + if (i + 1 != _baseLogger->getArrayVarCount()) { txBufferAppend(','); } else { @@ -205,5 +280,10 @@ int16_t EnviroDIYPublisher::publishData(Client* outClient) { PRINTOUT(F("\n-- Response Code --")); PRINTOUT(responseCode); + if (responseCode == 201) { + // data was successfully transmitted, we can discard it from the buffer + dataBufferNumRecords = 0; + } + return responseCode; } diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index c9b74c12e..e28495e37 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -219,6 +219,11 @@ class EnviroDIYPublisher : public dataPublisher { // queued sensor data buffer static char dataBuffer[MS_DATA_BUFFER_SIZE]; + // number of records currently in the buffer + static int dataBufferNumRecords; + + // actually transmit rather than just buffer data + int16_t flushDataBuffer(Client* outClient); private: // Tokens and UUID's for EnviroDIY From 74cac0df1d6cc69f3dbc9559c662faffd060216a Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 21:43:27 -0600 Subject: [PATCH 038/138] publishers/EnviroDIYPublisher: move log buffer logic to its own class Clean up and make maintenance easier --- src/LogBuffer.cpp | 90 +++++++++++++++++ src/LogBuffer.h | 138 ++++++++++++++++++++++++++ src/publishers/EnviroDIYPublisher.cpp | 108 ++++++++------------ src/publishers/EnviroDIYPublisher.h | 10 +- 4 files changed, 272 insertions(+), 74 deletions(-) create mode 100644 src/LogBuffer.cpp create mode 100644 src/LogBuffer.h diff --git a/src/LogBuffer.cpp b/src/LogBuffer.cpp new file mode 100644 index 000000000..5932ce614 --- /dev/null +++ b/src/LogBuffer.cpp @@ -0,0 +1,90 @@ +/** + * @file LogBuffer.cpp + * @copyright 2023 Thomas Watson + * Part of the EnviroDIY ModularSensors library for Arduino + * @author Thomas Watson + * + * @brief Implements the LogBuffer class. + * + * This class buffers logged timestamps and variable values for transmission. + */ +#include "LogBuffer.h" + +#include + +// Constructor +LogBuffer::LogBuffer() {} +// Destructor +LogBuffer::~LogBuffer() {} + +void LogBuffer::setNumVariables(uint8_t numVariables_) { + // each record is one uint32_t to hold the timestamp, plus N floats to hold + // each variable's value + recordSize = sizeof(uint32_t) + sizeof(float) * numVariables_; + numVariables = numVariables_; + + // this scrambles all the data in the buffer so clear it out + numRecords = 0; +} + +void LogBuffer::clear(void) { + // clear out the buffer + numRecords = 0; +} + +uint8_t LogBuffer::getNumVariables(void) { + return numVariables; +} + +int LogBuffer::getNumRecords(void) { + return numRecords; +} + +int LogBuffer::addRecord(uint32_t timestamp) { + int record = numRecords; + // compute position of the new record's timestamp in the buffer + // (the timestamp is the first data in the record) + size_t pos = record * recordSize; + // verify we have sufficient space for the record and bail if not + if (MS_LOG_DATA_BUFFER_SIZE - pos < recordSize) { return -1; } + + // write the timestamp to the record + memcpy(static_cast(&dataBuffer[pos]), static_cast(×tamp), + sizeof(uint32_t)); + numRecords += 1; // just added another record + + return record; +} + +void LogBuffer::setRecordValue(int record, uint8_t variable, float value) { + // compute position of this value in the buffer + size_t pos = record * recordSize + sizeof(uint32_t) + + variable * sizeof(float); + + // write the value to the record + memcpy(static_cast(&dataBuffer[pos]), static_cast(&value), + sizeof(float)); +} + +uint32_t LogBuffer::getRecordTimestamp(int record) { + // read the timestamp from the record (which is the first data in it) + uint32_t timestamp; + memcpy(static_cast(×tamp), + static_cast(&dataBuffer[record * recordSize]), + sizeof(uint32_t)); + + return timestamp; +} + +float LogBuffer::getRecordValue(int record, uint8_t variable) { + // compute position of this value in the buffer + size_t pos = record * recordSize + sizeof(uint32_t) + + variable * sizeof(float); + + // read the value from the record + float value; + memcpy(static_cast(&value), static_cast(&dataBuffer[pos]), + sizeof(float)); + + return value; +} diff --git a/src/LogBuffer.h b/src/LogBuffer.h new file mode 100644 index 000000000..4422a5608 --- /dev/null +++ b/src/LogBuffer.h @@ -0,0 +1,138 @@ +/** + * @file LogBuffer.cpp + * @copyright 2023 Thomas Watson + * Part of the EnviroDIY ModularSensors library for Arduino + * @author Thomas Watson + * + * @brief Implements the LogBuffer class. + * + * This class buffers logged timestamps and variable values for transmission. + */ + +// Header Guards +#ifndef SRC_LOGBUFFER_H_ +#define SRC_LOGBUFFER_H_ + +/** + * @def MS_LOG_DATA_BUFFER_SIZE + * @brief Log Data Buffer + * + * This determines how much RAM is reserved to buffer log records before + * transmission. Each record consumes 4 bytes for the timestamp plus 4 bytes + * for each logged variable. Increasing this value too far can crash the + * device! The number of log records buffered is controlled by sendEveryX. + * + * This can be changed by setting the build flag MS_LOG_DATA_BUFFER_SIZE when + * compiling. 8192 bytes is a safe value for the Mayfly 1.1 with six variables. + */ +#ifndef MS_LOG_DATA_BUFFER_SIZE +#define MS_LOG_DATA_BUFFER_SIZE 8192 +#endif + +#include +#include + +/** + * @brief This class buffers logged timestamps and variable values for + * transmission. The log is divided into a number of records. Each record + * stores the timestamp of the record as a uint32_t, then the value of each + * variable as a float at that time. + */ +class LogBuffer { + public: + /** + * @brief Constructs a new empty buffer which stores no variables or values. + */ + LogBuffer(); + /** + * @brief Destroys the buffer. + */ + virtual ~LogBuffer(); + + /** + * @brief Sets the number of variables the buffer will store in each record. + * Clears the buffer as a side effect. + * + * @param[in] numVariables_ The number of variables to store. + */ + void setNumVariables(uint8_t numVariables_); + + /** + * @brief Gets the number of variables that will be stored in each record. + * + * @return The variable count. + */ + uint8_t getNumVariables(void); + + /** + * @brief Clears all records from the log. + */ + void clear(void); + + /** + * @brief Gets the number of records currently in the log. + * + * @return The number of records. + */ + int getNumRecords(void); + + /** + * @brief Adds a new record with the given timestamp. + * + * @param[in] timestamp The timestamp + * + * @return Index of the new record, or -1 if there was no space. + */ + int addRecord(uint32_t timestamp); + + /** + * @brief Sets the value of a particular variable in a particular record. + * + * @param[in] record The record + * @param[in] variable The variable + * @param[in] value The value + */ + void setRecordValue(int record, uint8_t variable, float value); + + /** + * @brief Gets the timestamp of a particular record. + * + * @param[in] record The record + * + * @return The record's timestamp. + */ + uint32_t getRecordTimestamp(int record); + + /** + * @brief Gets the value of a particular vaiable in a particular record. + * + * @param[in] record The record + * @param[in] variable The variable + * + * @return The variable's value. + */ + float getRecordValue(int record, uint8_t variable); + + protected: + /** + * @brief Buffer which stores the log data. + */ + uint8_t dataBuffer[MS_LOG_DATA_BUFFER_SIZE]; + + /** + * @brief Number of records currently in the buffer. + */ + int numRecords; + + /** + * @brief Size in bytes of each record in the buffer. + */ + size_t recordSize; + + /** + * @brief Number of variables stored in each record in the buffer. + */ + uint8_t numVariables; +}; + +#endif // SRC_LOGBUFFER_H_ diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index 3b812ce3d..e43d05f95 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -11,8 +11,7 @@ #include "EnviroDIYPublisher.h" -char EnviroDIYPublisher::dataBuffer[MS_DATA_BUFFER_SIZE]; -int EnviroDIYPublisher::dataBufferNumRecords; +LogBuffer EnviroDIYPublisher::_logBuffer; // ============================================================================ // Functions for the EnviroDIY data portal receivers. @@ -48,6 +47,7 @@ EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, : dataPublisher(baseLogger, sendEveryX, sendOffset) { setToken(registrationToken); _baseLogger->setSamplingFeatureUUID(samplingFeatureUUID); + _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); } EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, Client* inClient, const char* registrationToken, @@ -56,6 +56,7 @@ EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, Client* inClient, : dataPublisher(baseLogger, inClient, sendEveryX, sendOffset) { setToken(registrationToken); _baseLogger->setSamplingFeatureUUID(samplingFeatureUUID); + _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); } // Destructor EnviroDIYPublisher::~EnviroDIYPublisher() {} @@ -68,35 +69,29 @@ void EnviroDIYPublisher::setToken(const char* registrationToken) { // Calculates how long the JSON will be uint16_t EnviroDIYPublisher::calculateJsonSize() { - char* ptr = (char*)&dataBuffer; - size_t recordSize = - sizeof(uint32_t)+sizeof(float)*_baseLogger->getArrayVarCount(); + uint8_t variables = _logBuffer.getNumVariables(); + int records = _logBuffer.getNumRecords(); uint16_t jsonLength = strlen(samplingFeatureTag); - jsonLength += 36; // sampling feature UUID + jsonLength += 36; // sampling feature UUID jsonLength += strlen(timestampTag); // markedISO8601Time + quotes and commas - jsonLength += dataBufferNumRecords * (25 + 2) + dataBufferNumRecords - 1; - jsonLength += 2; // ], - for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { + jsonLength += records * (25 + 2) + records - 1; + jsonLength += 2; // ], + for (uint8_t var = 0; var < variables; var++) { jsonLength += 1; // " jsonLength += 36; // variable UUID jsonLength += 4; // ":[] - ptr = (char*)&dataBuffer; - ptr += sizeof(uint32_t); // skip timestamp - ptr += i*sizeof(float); // and previous variables - for (int j = 0; j < dataBufferNumRecords; j++) { - float value; - memcpy((void*)&value, ptr, sizeof(float)); - ptr += recordSize; - - jsonLength += _baseLogger->formatValueStringAtI(i, value).length(); - if (j + 1 != dataBufferNumRecords) { - jsonLength += 1; // , + for (int rec = 0; rec < records; rec++) { + float value = _logBuffer.getRecordValue(rec, var); + jsonLength += + _baseLogger->formatValueStringAtI(var, value).length(); + if (rec + 1 != records) { + jsonLength += 1; // , } } - if (i + 1 != _baseLogger->getArrayVarCount()) { + if (var + 1 != variables) { jsonLength += 1; // , } } @@ -113,6 +108,7 @@ void EnviroDIYPublisher::begin(Logger& baseLogger, Client* inClient, setToken(registrationToken); dataPublisher::begin(baseLogger, inClient); _baseLogger->setSamplingFeatureUUID(samplingFeatureUUID); + _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); } void EnviroDIYPublisher::begin(Logger& baseLogger, const char* registrationToken, @@ -120,6 +116,7 @@ void EnviroDIYPublisher::begin(Logger& baseLogger, setToken(registrationToken); dataPublisher::begin(baseLogger); _baseLogger->setSamplingFeatureUUID(samplingFeatureUUID); + _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); } @@ -128,29 +125,22 @@ void EnviroDIYPublisher::begin(Logger& baseLogger, // over that connection. // The return is the http status code of the response. int16_t EnviroDIYPublisher::publishData(Client* outClient) { - // record timestamp and variable values into the data buffer + // create record to hold timestamp and variable values in the log buffer + int record = _logBuffer.addRecord(Logger::markedLocalEpochTime); - // compute where we will record to - size_t recordSize = - sizeof(uint32_t)+sizeof(float)*_baseLogger->getArrayVarCount(); - char* ptr = &dataBuffer[recordSize*dataBufferNumRecords]; - - memcpy(ptr, (void*)&Logger::markedLocalEpochTime, sizeof(uint32_t)); - ptr += sizeof(uint32_t); - - for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { - float value = _baseLogger->getValueAtI(i); - memcpy(ptr, (void*)&value, sizeof(float)); - ptr += sizeof(float); + // write record data if the record was successfully created + if (record >= 0) { + for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { + _logBuffer.setRecordValue(record, i, _baseLogger->getValueAtI(i)); + } } - dataBufferNumRecords += 1; - - if (dataBufferNumRecords == 2) { + // flush data if log buffer is full or we've hit the requested interval + if ((record >= 1) || (record < 0)) { return flushDataBuffer(outClient); } - return 201; // pretend everything went okay? + return 201; // pretend everything went okay? } int16_t EnviroDIYPublisher::flushDataBuffer(Client* outClient) { @@ -191,49 +181,35 @@ int16_t EnviroDIYPublisher::flushDataBuffer(Client* outClient) { txBufferAppend(timestampTag); // write out list of timestamps - char* ptr = (char*)&dataBuffer; - size_t recordSize = - sizeof(uint32_t)+sizeof(float)*_baseLogger->getArrayVarCount(); - for (int i = 0; i < dataBufferNumRecords; i++) { - uint32_t value; - memcpy((void*)&value, ptr, sizeof(uint32_t)); - ptr += recordSize; - + int records = _logBuffer.getNumRecords(); + for (int rec = 0; rec < records; rec++) { txBufferAppend('"'); - txBufferAppend(Logger::formatDateTime_ISO8601(value).c_str()); + uint32_t timestamp = _logBuffer.getRecordTimestamp(rec); + txBufferAppend(Logger::formatDateTime_ISO8601(timestamp).c_str()); txBufferAppend('"'); - if (i + 1 != dataBufferNumRecords) { - txBufferAppend(','); - } + if (rec + 1 != records) { txBufferAppend(','); } } txBufferAppend(']'); txBufferAppend(','); // write out a list of the values of each variable - for (uint8_t i = 0; i < _baseLogger->getArrayVarCount(); i++) { + uint8_t variables = _logBuffer.getNumVariables(); + for (uint8_t var = 0; var < variables; var++) { txBufferAppend('"'); - txBufferAppend(_baseLogger->getVarUUIDAtI(i).c_str()); + txBufferAppend(_baseLogger->getVarUUIDAtI(var).c_str()); txBufferAppend('"'); txBufferAppend(':'); txBufferAppend('['); - ptr = (char*)&dataBuffer; - ptr += sizeof(uint32_t); // skip timestamp - ptr += i*sizeof(float); // and previous variables - for (int j = 0; j < dataBufferNumRecords; j++) { - float value; - memcpy((void*)&value, ptr, sizeof(float)); - ptr += recordSize; - + for (int rec = 0; rec < records; rec++) { + float value = _logBuffer.getRecordValue(rec, var); txBufferAppend( - _baseLogger->formatValueStringAtI(i, value).c_str()); - if (j + 1 != dataBufferNumRecords) { - txBufferAppend(','); - } + _baseLogger->formatValueStringAtI(var, value).c_str()); + if (rec + 1 != records) { txBufferAppend(','); } } txBufferAppend(']'); - if (i + 1 != _baseLogger->getArrayVarCount()) { + if (var + 1 != variables) { txBufferAppend(','); } else { txBufferAppend('}'); @@ -282,7 +258,7 @@ int16_t EnviroDIYPublisher::flushDataBuffer(Client* outClient) { if (responseCode == 201) { // data was successfully transmitted, we can discard it from the buffer - dataBufferNumRecords = 0; + _logBuffer.clear(); } return responseCode; diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index e28495e37..b3afe1544 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -18,10 +18,6 @@ // Debugging Statement // #define MS_ENVIRODIYPUBLISHER_DEBUG -#ifndef MS_DATA_BUFFER_SIZE -#define MS_DATA_BUFFER_SIZE 8192 -#endif - #ifdef MS_ENVIRODIYPUBLISHER_DEBUG #define MS_DEBUGGING_STD "EnviroDIYPublisher" #endif @@ -30,6 +26,7 @@ #include "ModSensorDebugger.h" #undef MS_DEBUGGING_STD #include "dataPublisherBase.h" +#include "LogBuffer.h" // ============================================================================ @@ -217,10 +214,7 @@ class EnviroDIYPublisher : public dataPublisher { static const char* timestampTag; ///< The JSON feature timestamp tag /**@}*/ - // queued sensor data buffer - static char dataBuffer[MS_DATA_BUFFER_SIZE]; - // number of records currently in the buffer - static int dataBufferNumRecords; + static LogBuffer _logBuffer; // actually transmit rather than just buffer data int16_t flushDataBuffer(Client* outClient); From 1748f59dfc70f26843eb4cc018bfb9e915e8eed5 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 21:46:48 -0600 Subject: [PATCH 039/138] only turn modem on when internet connection is needed by a publisher Avoids unnecessary time and power consumption when publishers just plan to buffer the data. --- src/LoggerBase.cpp | 33 +++++++++++++++++++++++---- src/LoggerBase.h | 7 ++++++ src/dataPublisherBase.cpp | 14 +++++++----- src/dataPublisherBase.h | 8 +++++++ src/publishers/EnviroDIYPublisher.cpp | 3 +++ src/publishers/EnviroDIYPublisher.h | 8 +++++++ 6 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 7cc09cce4..e68b9c15f 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -354,6 +354,18 @@ void Logger::registerDataPublisher(dataPublisher* publisher) { dataPublishers[i] = publisher; } +bool Logger::checkRemotesConnectionNeeded(void) { + MS_DBG(F("Asking publishers if they need a connection.")); + + bool needed = false; + for (uint8_t i = 0; i < MAX_NUMBER_SENDERS; i++) { + if (dataPublishers[i] != nullptr) { + needed = needed || dataPublishers[i]->connectionNeeded(); + } + } + + return needed; +} void Logger::publishDataToRemotes(void) { MS_DBG(F("Sending out remote data.")); @@ -1536,7 +1548,15 @@ void Logger::logDataAndPublish(bool sleepBeforeReturning) { // Create a csv data record and save it to the log file logToSD(); - if (_logModem != nullptr) { + // Sync the clock at noon + bool clockSyncNeeded = + (Logger::markedLocalEpochTime != 0 && + Logger::markedLocalEpochTime % 86400 == 43200) || + !isRTCSane(Logger::markedLocalEpochTime); + bool connectionNeeded = checkRemotesConnectionNeeded() || + clockSyncNeeded; + + if (_logModem != nullptr && connectionNeeded) { MS_DBG(F("Waking up"), _logModem->getModemName(), F("...")); if (_logModem->modemWake()) { // Connect to the network @@ -1548,10 +1568,7 @@ void Logger::logDataAndPublish(bool sleepBeforeReturning) { publishDataToRemotes(); watchDogTimer.resetWatchDog(); - if ((Logger::markedLocalEpochTime != 0 && - Logger::markedLocalEpochTime % 86400 == 43200) || - !isRTCSane(Logger::markedLocalEpochTime)) { - // Sync the clock at noon + if (clockSyncNeeded) { MS_DBG(F("Running a daily clock sync...")); setRTClock(_logModem->getNISTTime()); watchDogTimer.resetWatchDog(); @@ -1571,6 +1588,12 @@ void Logger::logDataAndPublish(bool sleepBeforeReturning) { } // Turn the modem off _logModem->modemSleepPowerDown(); + } else if (_logModem != nullptr) { + MS_DBG(F("Nobody needs it so publishing without connecting...")); + // Call publish function without connection + watchDogTimer.resetWatchDog(); + publishDataToRemotes(); + watchDogTimer.resetWatchDog(); } diff --git a/src/LoggerBase.h b/src/LoggerBase.h index 21cafb22e..de3765af0 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -580,6 +580,13 @@ class Logger { * @param publisher A dataPublisher object */ void registerDataPublisher(dataPublisher* publisher); + /** + * @brief Check if any data publishers need an Internet connection for the + * next publish call. + * + * @return True if any remotes need a connection. + */ + bool checkRemotesConnectionNeeded(void); /** * @brief Publish data to all registered data publishers. */ diff --git a/src/dataPublisherBase.cpp b/src/dataPublisherBase.cpp index 1ad4a4d17..3534a04ad 100644 --- a/src/dataPublisherBase.cpp +++ b/src/dataPublisherBase.cpp @@ -10,9 +10,9 @@ */ #include "dataPublisherBase.h" -char dataPublisher::txBuffer[MS_SEND_BUFFER_SIZE]; +char dataPublisher::txBuffer[MS_SEND_BUFFER_SIZE]; Client* dataPublisher::txBufferOutClient = nullptr; -size_t dataPublisher::txBufferLen; +size_t dataPublisher::txBufferLen; // Basic chunks of HTTP const char* dataPublisher::getHeader = "GET "; @@ -84,16 +84,14 @@ void dataPublisher::txBufferInit(Client* outClient) { void dataPublisher::txBufferAppend(const char* data, size_t length) { while (length > 0) { size_t remaining = MS_SEND_BUFFER_SIZE - txBufferLen; - size_t amount = remaining < length ? remaining : length; + size_t amount = remaining < length ? remaining : length; memcpy(&txBuffer[txBufferLen], data, amount); length -= amount; data += amount; txBufferLen += amount; - if (txBufferLen == MS_SEND_BUFFER_SIZE) { - txBufferFlush(); - } + if (txBufferLen == MS_SEND_BUFFER_SIZE) { txBufferFlush(); } } } @@ -117,6 +115,10 @@ void dataPublisher::txBufferFlush() { txBufferLen = 0; } +bool dataPublisher::connectionNeeded(void) { + // connection is always needed unless publisher has special logic + return true; +} // This sends data on the "default" client of the modem int16_t dataPublisher::publishData() { diff --git a/src/dataPublisherBase.h b/src/dataPublisherBase.h index 91b4f9060..7851493a1 100644 --- a/src/dataPublisherBase.h +++ b/src/dataPublisherBase.h @@ -207,6 +207,14 @@ class dataPublisher { virtual String getEndpoint(void) = 0; + /** + * @brief Checks if the publisher needs an Internet connection for the next + * publishData call (as opposed to just buffering data internally). + * + * @return True if an internet connection is needed for the next publish. + */ + virtual bool connectionNeeded(void); + /** * @brief Open a socket to the correct receiver and sends out the formatted * data. diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index e43d05f95..82924417d 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -119,6 +119,9 @@ void EnviroDIYPublisher::begin(Logger& baseLogger, _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); } +bool EnviroDIYPublisher::connectionNeeded(void) { + return _logBuffer.getNumRecords() >= 1; +} // This utilizes an attached modem to make a TCP connection to the // EnviroDIY/ODM2DataSharingPortal and then streams out a post request diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index b3afe1544..36dd773b8 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -174,6 +174,14 @@ class EnviroDIYPublisher : public dataPublisher { void begin(Logger& baseLogger, const char* registrationToken, const char* samplingFeatureUUID); + /** + * @brief Checks if the publisher needs an Internet connection for the next + * publishData call (as opposed to just buffering data internally). + * + * @return True if an internet connection is needed for the next publish. + */ + bool connectionNeeded(void) override; + /** * @brief Utilize an attached modem to open a a TCP connection to the * EnviroDIY/ODM2DataSharingPortal and then stream out a post request over From 5d6908ab7fd568f72d8853393ce7c67dbc8e0eb2 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 21:49:37 -0600 Subject: [PATCH 040/138] dataPublisherBase: correctly retry flushing if modem buffer is full The modem might not be able to accept the data written to it if its transmit buffer is full. In that case, the portion not accepted needs to be retried later. If we retry too many times, give up so we don't get stuck in an infinite loop. --- src/dataPublisherBase.cpp | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/dataPublisherBase.cpp b/src/dataPublisherBase.cpp index 3534a04ad..b8d22a61b 100644 --- a/src/dataPublisherBase.cpp +++ b/src/dataPublisherBase.cpp @@ -104,15 +104,46 @@ void dataPublisher::txBufferAppend(char c) { } void dataPublisher::txBufferFlush() { + if ((txBufferOutClient == nullptr) || (txBufferLen == 0)) { + // sending into the void... + txBufferLen = 0; + return; + } + #if defined(STANDARD_SERIAL_OUTPUT) // send to debugging stream STANDARD_SERIAL_OUTPUT.write((const uint8_t*)txBuffer, txBufferLen); STANDARD_SERIAL_OUTPUT.flush(); #endif - txBufferOutClient->write((const uint8_t*)txBuffer, txBufferLen); - txBufferOutClient->flush(); - txBufferLen = 0; + uint8_t tries = 10; + const uint8_t* ptr = (const uint8_t*)txBuffer; + while (true) { + size_t sent = txBufferOutClient->write(ptr, txBufferLen); + txBufferLen -= sent; + ptr += sent; + if (txBufferLen == 0) { + // whole message is successfully sent, we are done + txBufferOutClient->flush(); + return; + } + +#if defined(STANDARD_SERIAL_OUTPUT) + // warn that we only partially sent the buffer + STANDARD_SERIAL_OUTPUT.write('!'); +#endif + if (--tries == 0) { + // can't convince the modem to send the whole message. just break + // the connection now so it will get reset and we can try to + // transmit the data again later + txBufferOutClient = nullptr; + txBufferLen = 0; + return; + } + + // give the modem a chance to transmit buffered data + delay(1000); + } } bool dataPublisher::connectionNeeded(void) { From 6f7a7f2097dc917ab84933f5fb83bab298676b68 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 21:52:07 -0600 Subject: [PATCH 041/138] publishers/EnviroDIYPublisher: increase transmission timeout Increases reliability of sending large transmissions. --- src/publishers/EnviroDIYPublisher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index 82924417d..34dfec190 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -222,9 +222,9 @@ int16_t EnviroDIYPublisher::flushDataBuffer(Client* outClient) { // Flush the complete request txBufferFlush(); - // Wait 10 seconds for a response from the server + // Wait 30 seconds for a response from the server uint32_t start = millis(); - while ((millis() - start) < 10000L && outClient->available() < 12) { + while ((millis() - start) < 30000L && outClient->available() < 12) { delay(10); } From 9c0e6a973e7706a6069761d08cd3aa00a0698d1b Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Sun, 5 Feb 2023 21:33:24 -0600 Subject: [PATCH 042/138] SIMComSIM7080: increase socket buffer size --- src/modems/SIMComSIM7080.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/modems/SIMComSIM7080.cpp b/src/modems/SIMComSIM7080.cpp index 4a644fe1a..b8e3c072f 100644 --- a/src/modems/SIMComSIM7080.cpp +++ b/src/modems/SIMComSIM7080.cpp @@ -33,7 +33,20 @@ SIMComSIM7080::SIMComSIM7080(Stream* modemStream, int8_t powerPin, // Destructor SIMComSIM7080::~SIMComSIM7080() {} -MS_MODEM_EXTRA_SETUP(SIMComSIM7080); +bool SIMComSIM7080::extraModemSetup(void) { + bool success = gsmModem.init(); + gsmClient.init(&gsmModem); + _modemName = gsmModem.getModemName(); + + // The modem is liable to crash if the send buffer overflows and TinyGSM + // offers no way to know when that might happen. Reduce the chance of + // problems by maxing out the send buffer size. This size should accommodate + // a completely full 8K LogBuffer and a crappy connection. + gsmModem.sendAT(F("+CACFG=\"SNDBUF\",29200")); + + return success; +} + MS_IS_MODEM_AWAKE(SIMComSIM7080); MS_MODEM_WAKE(SIMComSIM7080); From 9a011e04f8ecb2ff072eacc4874cc56f7fbac873 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Sun, 5 Feb 2023 23:14:29 -0600 Subject: [PATCH 043/138] LoggerBase: optimize setFileTimestamp Saves ~110 bytes of flash and substantial stack --- src/LoggerBase.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index e68b9c15f..552757d85 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -1091,12 +1091,10 @@ bool Logger::initializeSDCard(void) { // Protected helper function - This sets a timestamp on a file void Logger::setFileTimestamp(File fileToStamp, uint8_t stampFlag) { - fileToStamp.timestamp(stampFlag, dtFromEpoch(getNowLocalEpoch()).year(), - dtFromEpoch(getNowLocalEpoch()).month(), - dtFromEpoch(getNowLocalEpoch()).date(), - dtFromEpoch(getNowLocalEpoch()).hour(), - dtFromEpoch(getNowLocalEpoch()).minute(), - dtFromEpoch(getNowLocalEpoch()).second()); + DateTime dt = dtFromEpoch(getNowLocalEpoch()); + + fileToStamp.timestamp(stampFlag, dt.year(), dt.month(), dt.date(), + dt.hour(), dt.minute(), dt.second()); } From 6391c0c7094f56ebefa35af2765e856d1345ecec Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Sun, 5 Feb 2023 23:23:52 -0600 Subject: [PATCH 044/138] LoggerModem: optimize CSQ conversion functions Saves ~200 bytes of RAM and ~360 bytes of flash. The equations reproduce the tables previously found in the source code exactly. The reason for the values in the original tables is unknown. --- src/LoggerModem.cpp | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/LoggerModem.cpp b/src/LoggerModem.cpp index b44fa8159..15ca08ba4 100644 --- a/src/LoggerModem.cpp +++ b/src/LoggerModem.cpp @@ -394,31 +394,16 @@ float loggerModem::getModemTemperature() { // Helper to get approximate RSSI from CSQ (assuming no noise) int16_t loggerModem::getRSSIFromCSQ(int16_t csq) { - int16_t CSQs[33] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 99}; - int16_t RSSIs[33] = {-113, -111, -109, -107, -105, -103, -101, -99, -97, - -95, -93, -91, -89, -87, -85, -83, -81, -79, - -77, -75, -73, -71, -69, -67, -65, -63, -61, - -59, -57, -55, -53, -51, 0}; - for (uint8_t i = 0; i < 33; i++) { - if (CSQs[i] == csq) return RSSIs[i]; - } - return 0; + if ((csq < 0) || (csq > 31)) return 0; + // equation matches previous table. not sure the original motivation. + return ((csq * 2) - 113); } // Helper to get signal percent from CSQ int16_t loggerModem::getPctFromCSQ(int16_t csq) { - int16_t CSQs[33] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 99}; - int16_t PCTs[33] = {0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, - 36, 39, 42, 45, 48, 52, 55, 58, 61, 65, 68, - 71, 74, 78, 81, 84, 87, 90, 94, 97, 100, 0}; - for (uint8_t i = 0; i < 33; i++) { - if (CSQs[i] == csq) return PCTs[i]; - } - return 0; + if ((csq < 0) || (csq > 31)) return 0; + // equation matches previous table. not sure the original motivation. + return (csq * 827 + 127) >> 8; } // Helper to get signal percent from RSSI From 8d720f71cada4e3dee56437a86e48c93e76541b8 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 22:00:25 -0600 Subject: [PATCH 045/138] dataPublisherBase: repurpose sendEveryX and ditch sendOffset Use sendEveryX to set transmission interval for the EnviroDIY LogBuffer functionality. Delete sendOffset completely as there is little reason for that particular functionality. The offset is effectively set randomly by the time the datalogger initially powers on. --- src/dataPublisherBase.cpp | 18 ++++------ src/dataPublisherBase.h | 46 ++++++++------------------ src/publishers/DreamHostPublisher.cpp | 18 +++++----- src/publishers/DreamHostPublisher.h | 37 +++++++-------------- src/publishers/EnviroDIYPublisher.cpp | 21 ++++++------ src/publishers/EnviroDIYPublisher.h | 39 +++++++--------------- src/publishers/ThingSpeakPublisher.cpp | 17 +++++----- src/publishers/ThingSpeakPublisher.h | 38 +++++++-------------- src/publishers/UbidotsPublisher.cpp | 19 +++++------ src/publishers/UbidotsPublisher.h | 39 +++++++--------------- 10 files changed, 103 insertions(+), 189 deletions(-) diff --git a/src/dataPublisherBase.cpp b/src/dataPublisherBase.cpp index b8d22a61b..0c5e5cf15 100644 --- a/src/dataPublisherBase.cpp +++ b/src/dataPublisherBase.cpp @@ -23,19 +23,16 @@ const char* dataPublisher::hostHeader = "\r\nHost: "; // Constructors dataPublisher::dataPublisher() {} -dataPublisher::dataPublisher(Logger& baseLogger, uint8_t sendEveryX, - uint8_t sendOffset) +dataPublisher::dataPublisher(Logger& baseLogger, int sendEveryX) : _baseLogger(&baseLogger), - _sendEveryX(sendEveryX), - _sendOffset(sendOffset) { + _sendEveryX(sendEveryX) { _baseLogger->registerDataPublisher(this); // register self with logger } dataPublisher::dataPublisher(Logger& baseLogger, Client* inClient, - uint8_t sendEveryX, uint8_t sendOffset) + int sendEveryX) : _baseLogger(&baseLogger), _inClient(inClient), - _sendEveryX(sendEveryX), - _sendOffset(sendOffset) { + _sendEveryX(sendEveryX) { _baseLogger->registerDataPublisher(this); // register self with logger } // Destructor @@ -55,11 +52,10 @@ void dataPublisher::attachToLogger(Logger& baseLogger) { } -// Sets the parameters for frequency of sending and any offset, if needed -// NOTE: These parameters are not currently used!! -void dataPublisher::setSendFrequency(uint8_t sendEveryX, uint8_t sendOffset) { +// Sets the interval (in units of the logging interval) between attempted +// data transmissions +void dataPublisher::setSendInterval(int sendEveryX) { _sendEveryX = sendEveryX; - _sendOffset = sendOffset; } diff --git a/src/dataPublisherBase.h b/src/dataPublisherBase.h index 7851493a1..ccd70ab25 100644 --- a/src/dataPublisherBase.h +++ b/src/dataPublisherBase.h @@ -85,11 +85,8 @@ class dataPublisher { * logger. * * @param baseLogger The logger supplying the data to be published - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. Not respected by all publishers. * * @note It is possible (though very unlikey) that using this constructor * could cause errors if the compiler attempts to initialize the publisher @@ -97,8 +94,7 @@ class dataPublisher { * issue, use the null constructor and a populated begin(...) within your * set-up function. */ - explicit dataPublisher(Logger& baseLogger, uint8_t sendEveryX = 1, - uint8_t sendOffset = 0); + explicit dataPublisher(Logger& baseLogger, int sendEveryX = 1); /** * @brief Construct a new data Publisher object. * @@ -106,11 +102,8 @@ class dataPublisher { * @param inClient An Arduino client instance to use to print data to. * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. Not respected by all publishers. * * @note It is possible (though very unlikey) that using this constructor * could cause errors if the compiler attempts to initialize the publisher @@ -118,8 +111,7 @@ class dataPublisher { * issue, use the null constructor and a populated begin(...) within your * set-up function. */ - dataPublisher(Logger& baseLogger, Client* inClient, uint8_t sendEveryX = 1, - uint8_t sendOffset = 0); + dataPublisher(Logger& baseLogger, Client* inClient, int sendEveryX = 1); /** * @brief Destroy the data Publisher object - no action is taken. */ @@ -144,18 +136,13 @@ class dataPublisher { */ void attachToLogger(Logger& baseLogger); /** - * @brief Set the parameters for frequency of sending and any offset, if - * needed. + * @brief Sets the interval (in units of the logging interval) between + * attempted data transmissions * - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected - * - * @note These parameters are not currently used! + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. Not respected by all publishers. */ - void setSendFrequency(uint8_t sendEveryX, uint8_t sendOffset); + void setSendInterval(int sendEveryX); /** * @brief Begin the publisher - linking it to the client and logger. @@ -331,15 +318,10 @@ class dataPublisher { static void txBufferFlush(); /** - * @brief Unimplemented; intended for future use to enable caching and bulk - * publishing. - */ - uint8_t _sendEveryX = 1; - /** - * @brief Unimplemented; intended for future use to enable publishing data - * at a time slightly delayed from when it is collected. + * @brief Interval (in units of the logging interval) between + * attempted data transmissions. Not respected by all publishers. */ - uint8_t _sendOffset = 0; + int _sendEveryX = 1; // Basic chunks of HTTP /** diff --git a/src/publishers/DreamHostPublisher.cpp b/src/publishers/DreamHostPublisher.cpp index 5c3db12f6..74412523e 100644 --- a/src/publishers/DreamHostPublisher.cpp +++ b/src/publishers/DreamHostPublisher.cpp @@ -23,23 +23,21 @@ const char* DreamHostPublisher::timestampTagDH = "&Loggertime="; // Constructors DreamHostPublisher::DreamHostPublisher() : dataPublisher() {} -DreamHostPublisher::DreamHostPublisher(Logger& baseLogger, uint8_t sendEveryX, - uint8_t sendOffset) - : dataPublisher(baseLogger, sendEveryX, sendOffset) {} +DreamHostPublisher::DreamHostPublisher(Logger& baseLogger, int sendEveryX) + : dataPublisher(baseLogger, sendEveryX) {} DreamHostPublisher::DreamHostPublisher(Logger& baseLogger, Client* inClient, - uint8_t sendEveryX, uint8_t sendOffset) - : dataPublisher(baseLogger, inClient, sendEveryX, sendOffset) {} + int sendEveryX) + : dataPublisher(baseLogger, inClient, sendEveryX) {} DreamHostPublisher::DreamHostPublisher(Logger& baseLogger, const char* dhUrl, - uint8_t sendEveryX, uint8_t sendOffset) - : dataPublisher(baseLogger, sendEveryX, sendOffset) { + int sendEveryX) + : dataPublisher(baseLogger, sendEveryX) { setDreamHostPortalRX(dhUrl); } DreamHostPublisher::DreamHostPublisher(Logger& baseLogger, Client* inClient, - const char* dhUrl, uint8_t sendEveryX, - uint8_t sendOffset) - : dataPublisher(baseLogger, inClient, sendEveryX, sendOffset) { + const char* dhUrl, int sendEveryX) + : dataPublisher(baseLogger, inClient, sendEveryX) { setDreamHostPortalRX(dhUrl); } // Destructor diff --git a/src/publishers/DreamHostPublisher.h b/src/publishers/DreamHostPublisher.h index 584be2142..e7a8a6fb6 100644 --- a/src/publishers/DreamHostPublisher.h +++ b/src/publishers/DreamHostPublisher.h @@ -51,11 +51,8 @@ class DreamHostPublisher : public dataPublisher { * logger. * * @param baseLogger The logger supplying the data to be published - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. NOTE: not implemented by this publisher! * * @note It is possible (though very unlikey) that using this constructor * could cause errors if the compiler attempts to initialize the publisher @@ -63,8 +60,7 @@ class DreamHostPublisher : public dataPublisher { * issue, use the null constructor and a populated begin(...) within your * set-up function. */ - explicit DreamHostPublisher(Logger& baseLogger, uint8_t sendEveryX = 1, - uint8_t sendOffset = 0); + explicit DreamHostPublisher(Logger& baseLogger, int sendEveryX = 1); /** * @brief Construct a new DreamHost Publisher object * @@ -72,11 +68,8 @@ class DreamHostPublisher : public dataPublisher { * @param inClient An Arduino client instance to use to print data to. * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. NOTE: not implemented by this publisher! * * @note It is possible (though very unlikey) that using this constructor * could cause errors if the compiler attempts to initialize the publisher @@ -85,20 +78,17 @@ class DreamHostPublisher : public dataPublisher { * set-up function. */ DreamHostPublisher(Logger& baseLogger, Client* inClient, - uint8_t sendEveryX = 1, uint8_t sendOffset = 0); + int sendEveryX = 1); /** * @brief Construct a new DreamHost Publisher object * * @param baseLogger The logger supplying the data to be published * @param dhUrl The URL for sending data to DreamHost - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. NOTE: not implemented by this publisher! */ DreamHostPublisher(Logger& baseLogger, const char* dhUrl, - uint8_t sendEveryX = 1, uint8_t sendOffset = 0); + int sendEveryX = 1); /** * @brief Construct a new DreamHost Publisher object * @@ -107,14 +97,11 @@ class DreamHostPublisher : public dataPublisher { * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance * @param dhUrl The URL for sending data to DreamHost - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. NOTE: not implemented by this publisher! */ DreamHostPublisher(Logger& baseLogger, Client* inClient, const char* dhUrl, - uint8_t sendEveryX = 1, uint8_t sendOffset = 0); + int sendEveryX = 1); /** * @brief Destroy the DreamHost Publisher object */ diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index 34dfec190..339340a07 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -34,17 +34,16 @@ const char* EnviroDIYPublisher::timestampTag = "\",\"timestamp\":["; // Constructors EnviroDIYPublisher::EnviroDIYPublisher() : dataPublisher() {} -EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, uint8_t sendEveryX, - uint8_t sendOffset) - : dataPublisher(baseLogger, sendEveryX, sendOffset) {} +EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, int sendEveryX) + : dataPublisher(baseLogger, sendEveryX) {} EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, Client* inClient, - uint8_t sendEveryX, uint8_t sendOffset) - : dataPublisher(baseLogger, inClient, sendEveryX, sendOffset) {} + int sendEveryX) + : dataPublisher(baseLogger, inClient, sendEveryX) {} EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, const char* registrationToken, const char* samplingFeatureUUID, - uint8_t sendEveryX, uint8_t sendOffset) - : dataPublisher(baseLogger, sendEveryX, sendOffset) { + int sendEveryX) + : dataPublisher(baseLogger, sendEveryX) { setToken(registrationToken); _baseLogger->setSamplingFeatureUUID(samplingFeatureUUID); _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); @@ -52,8 +51,8 @@ EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, Client* inClient, const char* registrationToken, const char* samplingFeatureUUID, - uint8_t sendEveryX, uint8_t sendOffset) - : dataPublisher(baseLogger, inClient, sendEveryX, sendOffset) { + int sendEveryX) + : dataPublisher(baseLogger, inClient, sendEveryX) { setToken(registrationToken); _baseLogger->setSamplingFeatureUUID(samplingFeatureUUID); _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); @@ -120,7 +119,7 @@ void EnviroDIYPublisher::begin(Logger& baseLogger, } bool EnviroDIYPublisher::connectionNeeded(void) { - return _logBuffer.getNumRecords() >= 1; + return _logBuffer.getNumRecords() >= (_sendEveryX - 1); } // This utilizes an attached modem to make a TCP connection to the @@ -139,7 +138,7 @@ int16_t EnviroDIYPublisher::publishData(Client* outClient) { } // flush data if log buffer is full or we've hit the requested interval - if ((record >= 1) || (record < 0)) { + if ((record >= (_sendEveryX - 1)) || (record < 0)) { return flushDataBuffer(outClient); } diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index 36dd773b8..1320dccb6 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -54,11 +54,8 @@ class EnviroDIYPublisher : public dataPublisher { * logger. * * @param baseLogger The logger supplying the data to be published - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. * * @note It is possible (though very unlikey) that using this constructor * could cause errors if the compiler attempts to initialize the publisher @@ -66,8 +63,7 @@ class EnviroDIYPublisher : public dataPublisher { * issue, use the null constructor and a populated begin(...) within your * set-up function. */ - explicit EnviroDIYPublisher(Logger& baseLogger, uint8_t sendEveryX = 1, - uint8_t sendOffset = 0); + explicit EnviroDIYPublisher(Logger& baseLogger, int sendEveryX = 1); /** * @brief Construct a new EnviroDIY Publisher object * @@ -75,11 +71,8 @@ class EnviroDIYPublisher : public dataPublisher { * @param inClient An Arduino client instance to use to print data to. * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. * * @note It is possible (though very unlikey) that using this constructor * could cause errors if the compiler attempts to initialize the publisher @@ -88,7 +81,7 @@ class EnviroDIYPublisher : public dataPublisher { * set-up function. */ EnviroDIYPublisher(Logger& baseLogger, Client* inClient, - uint8_t sendEveryX = 1, uint8_t sendOffset = 0); + int sendEveryX = 1); /** * @brief Construct a new EnviroDIY Publisher object * @@ -97,15 +90,11 @@ class EnviroDIYPublisher : public dataPublisher { * Monitor My Watershed data portal. * @param samplingFeatureUUID The sampling feature UUID for the site on the * Monitor My Watershed data portal. - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. */ EnviroDIYPublisher(Logger& baseLogger, const char* registrationToken, - const char* samplingFeatureUUID, uint8_t sendEveryX = 1, - uint8_t sendOffset = 0); + const char* samplingFeatureUUID, int sendEveryX = 1); /** * @brief Construct a new EnviroDIY Publisher object * @@ -117,16 +106,12 @@ class EnviroDIYPublisher : public dataPublisher { * Monitor My Watershed data portal. * @param samplingFeatureUUID The sampling feature UUID for the site on the * Monitor My Watershed data portal. - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. */ EnviroDIYPublisher(Logger& baseLogger, Client* inClient, const char* registrationToken, - const char* samplingFeatureUUID, uint8_t sendEveryX = 1, - uint8_t sendOffset = 0); + const char* samplingFeatureUUID, int sendEveryX = 1); /** * @brief Destroy the EnviroDIY Publisher object */ diff --git a/src/publishers/ThingSpeakPublisher.cpp b/src/publishers/ThingSpeakPublisher.cpp index 1a020434e..a00e3c3e7 100644 --- a/src/publishers/ThingSpeakPublisher.cpp +++ b/src/publishers/ThingSpeakPublisher.cpp @@ -25,18 +25,17 @@ const char* ThingSpeakPublisher::mqttUser = THING_SPEAK_USER_NAME; // Constructors ThingSpeakPublisher::ThingSpeakPublisher() : dataPublisher() {} -ThingSpeakPublisher::ThingSpeakPublisher(Logger& baseLogger, uint8_t sendEveryX, - uint8_t sendOffset) - : dataPublisher(baseLogger, sendEveryX, sendOffset) {} +ThingSpeakPublisher::ThingSpeakPublisher(Logger& baseLogger, int sendEveryX) + : dataPublisher(baseLogger, sendEveryX) {} ThingSpeakPublisher::ThingSpeakPublisher(Logger& baseLogger, Client* inClient, - uint8_t sendEveryX, uint8_t sendOffset) - : dataPublisher(baseLogger, inClient, sendEveryX, sendOffset) {} + int sendEveryX) + : dataPublisher(baseLogger, inClient, sendEveryX) {} ThingSpeakPublisher::ThingSpeakPublisher(Logger& baseLogger, const char* thingSpeakMQTTKey, const char* thingSpeakChannelID, const char* thingSpeakChannelKey, - uint8_t sendEveryX, uint8_t sendOffset) - : dataPublisher(baseLogger, sendEveryX, sendOffset) { + int sendEveryX) + : dataPublisher(baseLogger, sendEveryX) { setMQTTKey(thingSpeakMQTTKey); setChannelID(thingSpeakChannelID); setChannelKey(thingSpeakChannelKey); @@ -45,8 +44,8 @@ ThingSpeakPublisher::ThingSpeakPublisher(Logger& baseLogger, Client* inClient, const char* thingSpeakMQTTKey, const char* thingSpeakChannelID, const char* thingSpeakChannelKey, - uint8_t sendEveryX, uint8_t sendOffset) - : dataPublisher(baseLogger, inClient, sendEveryX, sendOffset) { + int sendEveryX) + : dataPublisher(baseLogger, inClient, sendEveryX) { setMQTTKey(thingSpeakMQTTKey); setChannelID(thingSpeakChannelID); setChannelKey(thingSpeakChannelKey); diff --git a/src/publishers/ThingSpeakPublisher.h b/src/publishers/ThingSpeakPublisher.h index fcb215bf7..e61b9ec49 100644 --- a/src/publishers/ThingSpeakPublisher.h +++ b/src/publishers/ThingSpeakPublisher.h @@ -76,11 +76,8 @@ class ThingSpeakPublisher : public dataPublisher { * logger. * * @param baseLogger The logger supplying the data to be published - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. NOTE: not implemented by this publisher! * * @note It is possible (though very unlikey) that using this constructor * could cause errors if the compiler attempts to initialize the publisher @@ -88,8 +85,7 @@ class ThingSpeakPublisher : public dataPublisher { * issue, use the null constructor and a populated begin(...) within your * set-up function. */ - explicit ThingSpeakPublisher(Logger& baseLogger, uint8_t sendEveryX = 1, - uint8_t sendOffset = 0); + explicit ThingSpeakPublisher(Logger& baseLogger, int sendEveryX = 1); /** * @brief Construct a new ThingSpeak Publisher object * @@ -97,11 +93,8 @@ class ThingSpeakPublisher : public dataPublisher { * @param inClient An Arduino client instance to use to print data to. * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. NOTE: not implemented by this publisher! * * @note It is possible (though very unlikey) that using this constructor * could cause errors if the compiler attempts to initialize the publisher @@ -110,7 +103,7 @@ class ThingSpeakPublisher : public dataPublisher { * set-up function. */ ThingSpeakPublisher(Logger& baseLogger, Client* inClient, - uint8_t sendEveryX = 1, uint8_t sendOffset = 0); + int sendEveryX = 1); /** * @brief Construct a new ThingSpeak Publisher object * @@ -118,15 +111,12 @@ class ThingSpeakPublisher : public dataPublisher { * @param thingSpeakMQTTKey Your MQTT API Key from Account > MyProfile. * @param thingSpeakChannelID The numeric channel id for your channel * @param thingSpeakChannelKey The write API key for your channel - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. NOTE: not implemented by this publisher! */ ThingSpeakPublisher(Logger& baseLogger, const char* thingSpeakMQTTKey, const char* thingSpeakChannelID, - const char* thingSpeakChannelKey, - uint8_t sendEveryX = 1, uint8_t sendOffset = 0); + const char* thingSpeakChannelKey, int sendEveryX = 1); /** * @brief Construct a new ThingSpeak Publisher object * @@ -137,17 +127,13 @@ class ThingSpeakPublisher : public dataPublisher { * @param thingSpeakMQTTKey Your MQTT API Key from Account > MyProfile. * @param thingSpeakChannelID The numeric channel id for your channel * @param thingSpeakChannelKey The write API key for your channel - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. NOTE: not implemented by this publisher! */ ThingSpeakPublisher(Logger& baseLogger, Client* inClient, const char* thingSpeakMQTTKey, const char* thingSpeakChannelID, - const char* thingSpeakChannelKey, - uint8_t sendEveryX = 1, uint8_t sendOffset = 0); + const char* thingSpeakChannelKey, int sendEveryX = 1); /** * @brief Destroy the ThingSpeak Publisher object */ diff --git a/src/publishers/UbidotsPublisher.cpp b/src/publishers/UbidotsPublisher.cpp index c1e781d62..5477345a4 100644 --- a/src/publishers/UbidotsPublisher.cpp +++ b/src/publishers/UbidotsPublisher.cpp @@ -34,26 +34,23 @@ const char* UbidotsPublisher::payload = "{"; // Constructors UbidotsPublisher::UbidotsPublisher() : dataPublisher() {} -UbidotsPublisher::UbidotsPublisher(Logger& baseLogger, uint8_t sendEveryX, - uint8_t sendOffset) - : dataPublisher(baseLogger, sendEveryX, sendOffset) {} +UbidotsPublisher::UbidotsPublisher(Logger& baseLogger, int sendEveryX) + : dataPublisher(baseLogger, sendEveryX) {} UbidotsPublisher::UbidotsPublisher(Logger& baseLogger, Client* inClient, - uint8_t sendEveryX, uint8_t sendOffset) - : dataPublisher(baseLogger, inClient, sendEveryX, sendOffset) {} + int sendEveryX) + : dataPublisher(baseLogger, inClient, sendEveryX) {} UbidotsPublisher::UbidotsPublisher(Logger& baseLogger, const char* authentificationToken, - const char* deviceID, uint8_t sendEveryX, - uint8_t sendOffset) - : dataPublisher(baseLogger, sendEveryX, sendOffset) { + const char* deviceID, int sendEveryX) + : dataPublisher(baseLogger, sendEveryX) { setToken(authentificationToken); _baseLogger->setSamplingFeatureUUID(deviceID); MS_DBG(F("dataPublisher object created")); } UbidotsPublisher::UbidotsPublisher(Logger& baseLogger, Client* inClient, const char* authentificationToken, - const char* deviceID, uint8_t sendEveryX, - uint8_t sendOffset) - : dataPublisher(baseLogger, inClient, sendEveryX, sendOffset) { + const char* deviceID, int sendEveryX) + : dataPublisher(baseLogger, inClient, sendEveryX) { setToken(authentificationToken); _baseLogger->setSamplingFeatureUUID(deviceID); MS_DBG(F("dataPublisher object created")); diff --git a/src/publishers/UbidotsPublisher.h b/src/publishers/UbidotsPublisher.h index 1562890c6..94853c79a 100644 --- a/src/publishers/UbidotsPublisher.h +++ b/src/publishers/UbidotsPublisher.h @@ -50,11 +50,8 @@ class UbidotsPublisher : public dataPublisher { * logger. * * @param baseLogger The logger supplying the data to be published - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. NOTE: not implemented by this publisher! * * @note It is possible (though very unlikey) that using this constructor * could cause errors if the compiler attempts to initialize the publisher @@ -62,8 +59,7 @@ class UbidotsPublisher : public dataPublisher { * issue, use the null constructor and a populated begin(...) within your * set-up function. */ - explicit UbidotsPublisher(Logger& baseLogger, uint8_t sendEveryX = 1, - uint8_t sendOffset = 0); + explicit UbidotsPublisher(Logger& baseLogger, int sendEveryX = 1); /** * @brief Construct a new Ubidots Publisher object * @@ -71,11 +67,8 @@ class UbidotsPublisher : public dataPublisher { * @param inClient An Arduino client instance to use to print data to. * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. NOTE: not implemented by this publisher! * * @note It is possible (though very unlikey) that using this constructor * could cause errors if the compiler attempts to initialize the publisher @@ -83,8 +76,7 @@ class UbidotsPublisher : public dataPublisher { * issue, use the null constructor and a populated begin(...) within your * set-up function. */ - UbidotsPublisher(Logger& baseLogger, Client* inClient, - uint8_t sendEveryX = 1, uint8_t sendOffset = 0); + UbidotsPublisher(Logger& baseLogger, Client* inClient, int sendEveryX = 1); /** * @brief Construct a new Ubidots Publisher object * @@ -95,15 +87,11 @@ class UbidotsPublisher : public dataPublisher { * specific device's setup panel). * @param deviceID The device API Label from Ubidots, derived from the * user-specified device name. - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. NOTE: not implemented by this publisher! */ UbidotsPublisher(Logger& baseLogger, const char* authentificationToken, - const char* deviceID, uint8_t sendEveryX = 1, - uint8_t sendOffset = 0); + const char* deviceID, int sendEveryX = 1); /** * @brief Construct a new Ubidots Publisher object * @@ -117,15 +105,12 @@ class UbidotsPublisher : public dataPublisher { * specific device's setup panel). * @param deviceID The device API Label from Ubidots, derived from the * user-specified device name. - * @param sendEveryX Currently unimplemented, intended for future use to - * enable caching and bulk publishing - * @param sendOffset Currently unimplemented, intended for future use to - * enable publishing data at a time slightly delayed from when it is - * collected + * @param sendEveryX Interval (in units of the logging interval) between + * attempted data transmissions. NOTE: not implemented by this publisher! */ UbidotsPublisher(Logger& baseLogger, Client* inClient, const char* authentificationToken, const char* deviceID, - uint8_t sendEveryX = 1, uint8_t sendOffset = 0); + int sendEveryX = 1); /** * @brief Destroy the EnviroDIY Publisher object */ From 80e7bda6e41de2d065f05d178714b202ea3fb87e Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Mon, 6 Feb 2023 23:51:08 -0600 Subject: [PATCH 046/138] LoggerBase: always power down modem after RTC sync The test for "15 seconds before the next logging interval" has been wrong for years, possibly since this code was written, with no apparent consequence. The behavior is additionally confusing to users deploying the devices and causes problems with logging as the modem won't get turned off for a long time. Remove it completely to solve the problems. --- src/LoggerBase.cpp | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 552757d85..f100d8d51 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -314,25 +314,11 @@ bool Logger::syncRTC() { PRINTOUT(F("Could not wake modem for clock sync.")); } watchDogTimer.resetWatchDog(); - // Power down the modem - but only if there will be more than 15 seconds - // before the NEXT logging interval - it can take the modem that long to - // shut down - - uint32_t setupFinishTime = getNowLocalEpoch(); - if (setupFinishTime % (_loggingIntervalMinutes * 60) > 15) { - MS_DBG(F("At"), formatDateTime_ISO8601(setupFinishTime), F("with"), - setupFinishTime % (_loggingIntervalMinutes * 60), - F("seconds until next logging interval, putting modem to " - "sleep")); - _logModem->disconnectInternet(); - _logModem->modemSleepPowerDown(); - } else { - MS_DBG(F("At"), formatDateTime_ISO8601(setupFinishTime), - F("there are only"), - setupFinishTime % (_loggingIntervalMinutes * 60), - F("seconds until next logging interval; leaving modem on " - "and connected to the internet.")); - } + + // Power down the modem now that we are done with it + MS_DBG(F("Powering down modem after clock sync.")); + _logModem->disconnectInternet(); + _logModem->modemSleepPowerDown(); } watchDogTimer.resetWatchDog(); return success; From 82ccf93ffaf5139cf1322f7dd5675e16824dd9ac Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 22:07:25 -0600 Subject: [PATCH 047/138] publishers/EnviroDIYPublisher: send initial logged data immediately Send the first few data points logged after initialization immediately instead of buffering them until the programmed interval elapses. Allows verification of functionality during deployment. --- src/publishers/EnviroDIYPublisher.cpp | 26 +++++++++++++++++++++----- src/publishers/EnviroDIYPublisher.h | 4 ++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index 339340a07..6cde8cb79 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -119,7 +119,14 @@ void EnviroDIYPublisher::begin(Logger& baseLogger, } bool EnviroDIYPublisher::connectionNeeded(void) { - return _logBuffer.getNumRecords() >= (_sendEveryX - 1); + // the programmed interval is about to be reached by the next record + bool atSendInterval = _logBuffer.getNumRecords() >= (_sendEveryX - 1); + + // the initial log transmissions have not completed (we send every one + // of the first five data points immediately for field validation) + bool initialTransmission = _initialTransmissionsRemaining > 0; + + return atSendInterval || initialTransmission; } // This utilizes an attached modem to make a TCP connection to the @@ -127,6 +134,11 @@ bool EnviroDIYPublisher::connectionNeeded(void) { // over that connection. // The return is the http status code of the response. int16_t EnviroDIYPublisher::publishData(Client* outClient) { + // do we intend to send this call? if so, we have just returned true from + // connectionNeeded() and the internet is connected and waiting. check what + // that function said so we know to do it after we record this data point. + bool willFlush = connectionNeeded(); + // create record to hold timestamp and variable values in the log buffer int record = _logBuffer.addRecord(Logger::markedLocalEpochTime); @@ -137,12 +149,16 @@ int16_t EnviroDIYPublisher::publishData(Client* outClient) { } } - // flush data if log buffer is full or we've hit the requested interval - if ((record >= (_sendEveryX - 1)) || (record < 0)) { - return flushDataBuffer(outClient); + if (_initialTransmissionsRemaining > 0) { + _initialTransmissionsRemaining -= 1; } - return 201; // pretend everything went okay? + // do the data buffer flushing if we previously planned to + if (willFlush) { + return flushDataBuffer(outClient); + } else { + return 201; // pretend everything went okay? + } } int16_t EnviroDIYPublisher::flushDataBuffer(Client* outClient) { diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index 1320dccb6..b984f08c1 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -212,6 +212,10 @@ class EnviroDIYPublisher : public dataPublisher { // actually transmit rather than just buffer data int16_t flushDataBuffer(Client* outClient); + // we send every one of the first five data points immediately for field + // validation + uint8_t _initialTransmissionsRemaining = 5; + private: // Tokens and UUID's for EnviroDIY const char* _registrationToken = nullptr; From 49842490c2825158b230f6459269ceb35b349f7b Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 22:16:08 -0600 Subject: [PATCH 048/138] publishers/EnviroDIYPublisher: use more intelligent sending algorithm Avoid repeatedly retrying if the server is down, while still retrying a couple times in case the connection is unreliable. --- src/LogBuffer.cpp | 7 ++++++ src/LogBuffer.h | 7 ++++++ src/publishers/EnviroDIYPublisher.cpp | 36 +++++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/LogBuffer.cpp b/src/LogBuffer.cpp index 5932ce614..46c05ef56 100644 --- a/src/LogBuffer.cpp +++ b/src/LogBuffer.cpp @@ -40,6 +40,13 @@ int LogBuffer::getNumRecords(void) { return numRecords; } +uint8_t LogBuffer::getPercentFull(void) { + uint32_t bytesFull = (uint32_t)numRecords * (uint32_t)recordSize; + uint32_t bytesTotal = MS_LOG_DATA_BUFFER_SIZE; + + return (uint8_t)((bytesFull*(uint32_t)100)/bytesTotal); +} + int LogBuffer::addRecord(uint32_t timestamp) { int record = numRecords; // compute position of the new record's timestamp in the buffer diff --git a/src/LogBuffer.h b/src/LogBuffer.h index 4422a5608..b4b241a53 100644 --- a/src/LogBuffer.h +++ b/src/LogBuffer.h @@ -76,6 +76,13 @@ class LogBuffer { */ int getNumRecords(void); + /** + * @brief Computes the percentage full of the buffer. + * + * @return The current percent full. + */ + uint8_t getPercentFull(void); + /** * @brief Adds a new record with the given timestamp. * diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index 6cde8cb79..280f35e38 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -119,8 +119,40 @@ void EnviroDIYPublisher::begin(Logger& baseLogger, } bool EnviroDIYPublisher::connectionNeeded(void) { - // the programmed interval is about to be reached by the next record - bool atSendInterval = _logBuffer.getNumRecords() >= (_sendEveryX - 1); + // compute the send interval, reducing it as the buffer gets more full so we + // have less of a chance of losing data + int interval = _sendEveryX; + uint8_t percent = _logBuffer.getPercentFull(); + if (percent >= 50) { + interval /= 2; + } else if (percent >= 75) { + interval /= 4; + } else if (percent >= 90) { + interval = 1; + } + + // the programmed interval is about to be reached by the next record, or it + // was just reached and we are trying again + bool atSendInterval = false; + if (interval <= 1) { + atSendInterval = true; + } else { + int numRecords = _logBuffer.getNumRecords(); + // where we are relative to the interval + int relative = (numRecords % interval); + if (relative == (interval - 1)) { + // the next sample will put us right at the interval + atSendInterval = true; + } else if (numRecords >= interval) { // don't send the first sample + if (relative == 0) { + // the last sample was the interval, this is the first retry + atSendInterval = true; + } else if (relative == 1) { + // two samples ago was the interval, this is the second retry + atSendInterval = true; + } + } + } // the initial log transmissions have not completed (we send every one // of the first five data points immediately for field validation) From b0afb67467e59a10a8e2f00a8465848e6468fdd1 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 00:27:56 -0600 Subject: [PATCH 049/138] LoggerBase: force 1 minute logging interval for first 5 samples Allows field verification of logger functionality after deployment without undue delay. --- src/LoggerBase.cpp | 14 +++++++++++--- src/LoggerBase.h | 5 +++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index f100d8d51..5c438ba00 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -602,13 +602,21 @@ void Logger::markTime(void) { bool Logger::checkInterval(void) { bool retval; uint32_t checkTime = getNowLocalEpoch(); + uint16_t interval = _loggingIntervalMinutes; + if (_initialShortIntervals > 0) { + // log the first few samples at an interval of 1 minute so that + // operation can be quickly verified in the field + _initialShortIntervals -= 1; + interval = 1; + } + MS_DBG(F("Current Unix Timestamp:"), checkTime, F("->"), formatDateTime_ISO8601(checkTime)); - MS_DBG(F("Logging interval in seconds:"), (_loggingIntervalMinutes * 60)); + MS_DBG(F("Logging interval in seconds:"), (interval * 60)); MS_DBG(F("Mod of Logging Interval:"), - checkTime % (_loggingIntervalMinutes * 60)); + checkTime % (interval * 60)); - if (checkTime % (_loggingIntervalMinutes * 60) == 0) { + if (checkTime % (interval * 60) == 0) { // Update the time variables with the current time markTime(); MS_DBG(F("Time marked at (unix):"), Logger::markedLocalEpochTime); diff --git a/src/LoggerBase.h b/src/LoggerBase.h index de3765af0..efbe1b401 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -391,6 +391,11 @@ class Logger { * @brief The logging interval in minutes */ uint16_t _loggingIntervalMinutes = 5; + /** + * @brief The initial number of samples to log at an interval of 1 minute + * for fast field verification + */ + uint8_t _initialShortIntervals = 5; /** * @brief Digital pin number on the mcu controlling the SD card slave * select. From 7165c785ff278365fccfdb7705ad94431851504a Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 12:46:28 -0600 Subject: [PATCH 050/138] LoggerBase: make testing button log immediately using normal procedure Allows easy field verification of functionality as opposed to previous testing function which only served a purpose when attached to a computer (and consumed lots of flash). --- src/LoggerBase.cpp | 118 +++++---------------------------------------- src/LoggerBase.h | 18 ------- 2 files changed, 11 insertions(+), 125 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 5c438ba00..2238ef58c 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -31,7 +31,6 @@ uint32_t Logger::markedLocalEpochTime = 0; uint32_t Logger::markedUTCEpochTime = 0; // Initialize the testing/logging flags volatile bool Logger::isLoggingNow = false; -volatile bool Logger::isTestingNow = false; volatile bool Logger::startTesting = false; // Initialize the RTC for the SAMD boards @@ -52,7 +51,6 @@ Logger::Logger(const char* loggerID, uint16_t loggingIntervalMinutes, // Set the testing/logging flags to false isLoggingNow = false; - isTestingNow = false; startTesting = false; // Set the initial pin values @@ -73,7 +71,6 @@ Logger::Logger(const char* loggerID, uint16_t loggingIntervalMinutes, // Set the testing/logging flags to false isLoggingNow = false; - isTestingNow = false; startTesting = false; // Clear arrays @@ -84,7 +81,6 @@ Logger::Logger(const char* loggerID, uint16_t loggingIntervalMinutes, Logger::Logger() { // Set the testing/logging flags to false isLoggingNow = false; - isTestingNow = false; startTesting = false; // Clear arrays @@ -616,7 +612,7 @@ bool Logger::checkInterval(void) { MS_DBG(F("Mod of Logging Interval:"), checkTime % (interval * 60)); - if (checkTime % (interval * 60) == 0) { + if ((checkTime % (interval * 60) == 0) || Logger::startTesting) { // Update the time variables with the current time markTime(); MS_DBG(F("Time marked at (unix):"), Logger::markedLocalEpochTime); @@ -1256,106 +1252,13 @@ bool Logger::logToSD(void) { // A static function if you'd prefer to enter testing based on an interrupt void Logger::testingISR() { MS_DEEP_DBG(F("Testing interrupt!")); - if (!Logger::isTestingNow && !Logger::isLoggingNow) { + if (!Logger::isLoggingNow) { Logger::startTesting = true; MS_DEEP_DBG(F("Testing flag has been set.")); } } -// This defines what to do in the testing mode -void Logger::testingMode(bool sleepBeforeReturning) { - // Flag to notify that we're in testing mode - Logger::isTestingNow = true; - // Unset the startTesting flag - Logger::startTesting = false; - - PRINTOUT(F("------------------------------------------")); - PRINTOUT(F("Entering sensor testing mode")); - delay(100); // This seems to prevent crashes, no clue why .... - - // Get the modem ready - - bool gotInternetConnection = false; - if (_logModem != nullptr) { - MS_DBG(F("Waking up"), _logModem->getModemName(), F("...")); - if (_logModem->modemWake()) { - // Connect to the network - watchDogTimer.resetWatchDog(); - MS_DBG(F("Connecting to the Internet...")); - if (_logModem->connectInternet()) { - gotInternetConnection = true; - // Publish data to remotes - watchDogTimer.resetWatchDog(); - } - } - } - - // Power up all of the sensors - _internalArray->sensorsPowerUp(); - - // Wake up all of the sensors - _internalArray->sensorsWake(); - - // Update the sensors and print out data 25 times - for (uint8_t i = 0; i < 25; i++) { - PRINTOUT(F("------------------------------------------")); - - // Update the modem metadata - // NOTE: the extra get signal quality is an annoying redundancy - // needed only for the wifi XBee. Update metadata will also ask the - // module for current signal quality using the underlying TinyGSM - // getSignalQuality() function, but for the WiFi XBee it will not - // actually measure anything except by explicitly making a connection, - // which getModemSignalQuality() does. For all of the other modules, - // getModemSignalQuality() is just a straight pass-through to - // getSignalQuality(). - if (gotInternetConnection) { _logModem->updateModemMetadata(); } - - watchDogTimer.resetWatchDog(); - // Update the values from all attached sensors - // NOTE: NOT using complete update because we want the sensors to be - // left on between iterations in testing mode. - _internalArray->updateAllSensors(); - // Print out the current logger time - PRINTOUT(F("Current logger time is"), - formatDateTime_ISO8601(getNowLocalEpoch())); - PRINTOUT(F("-----------------------")); -// Print out the sensor data -#if defined(STANDARD_SERIAL_OUTPUT) - _internalArray->printSensorData(&STANDARD_SERIAL_OUTPUT); -#endif - PRINTOUT(F("-----------------------")); - watchDogTimer.resetWatchDog(); - - delay(5000); - watchDogTimer.resetWatchDog(); - } - - // Put sensors to sleep - _internalArray->sensorsSleep(); - _internalArray->sensorsPowerDown(); - - // Turn the modem off - if (_logModem != nullptr) { - if (gotInternetConnection) { _logModem->disconnectInternet(); } - _logModem->modemSleepPowerDown(); - } - - PRINTOUT(F("Exiting testing mode")); - PRINTOUT(F("------------------------------------------")); - watchDogTimer.resetWatchDog(); - - // Unset testing mode flag - Logger::isTestingNow = false; - - if (sleepBeforeReturning) { - // Sleep - systemSleep(); - } -} - - // ===================================================================== // // Convience functions to call several of the above functions // ===================================================================== // @@ -1454,10 +1357,12 @@ void Logger::logData(bool sleepBeforeReturning) { watchDogTimer.resetWatchDog(); // Assuming we were woken up by the clock, check if the current time is an - // even interval of the logging interval + // even interval of the logging interval or that we have been specifically + // requested to log by pushbutton if (checkInterval()) { // Flag to notify that we're in already awake and logging a point Logger::isLoggingNow = true; + // Reset the watchdog watchDogTimer.resetWatchDog(); @@ -1488,11 +1393,10 @@ void Logger::logData(bool sleepBeforeReturning) { // Unset flag Logger::isLoggingNow = false; + // Acknowledge testing button if pressed + Logger::startTesting = false; } - // Check if it was instead the testing interrupt that woke us up - if (Logger::startTesting) testingMode(); - if (sleepBeforeReturning) { // Sleep systemSleep(); @@ -1504,7 +1408,8 @@ void Logger::logDataAndPublish(bool sleepBeforeReturning) { watchDogTimer.resetWatchDog(); // Assuming we were woken up by the clock, check if the current time is an - // even interval of the logging interval + // even interval of the logging interval or that we have been specifically + // requested to log by pushbutton if (checkInterval()) { // Flag to notify that we're in already awake and logging a point Logger::isLoggingNow = true; @@ -1603,11 +1508,10 @@ void Logger::logDataAndPublish(bool sleepBeforeReturning) { // Unset flag Logger::isLoggingNow = false; + // Acknowledge testing button if pressed + Logger::startTesting = false; } - // Check if it was instead the testing interrupt that woke us up - if (Logger::startTesting) testingMode(sleepBeforeReturning); - if (sleepBeforeReturning) { // Sleep systemSleep(); diff --git a/src/LoggerBase.h b/src/LoggerBase.h index efbe1b401..e8d5a0e4d 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -1121,19 +1121,6 @@ class Logger { * on the pin assigned for "testing" mode. */ static void testingISR(void); - - /** - * @brief Execute testing mode. - * - * In testing mode, the logger uses the loggerModem, if attached, to connect - * to the internet. It then powers up all sensors tied to variable in the - * internal variable array. The logger then updates readings from all - * sensors 25 times with a 5 second wait in between. All results are output - * to the "main" output - ie Serial - and NOT to the SD card. After 25 - * measurements, the sensors are put to sleep, the modem is disconnected - * from the internet, and the logger goes back to sleep. - */ - virtual void testingMode(bool sleepBeforeReturning = true); /**@}*/ // ===================================================================== // @@ -1217,11 +1204,6 @@ class Logger { * sensors or writing to the SD card */ static volatile bool isLoggingNow; - /** - * @brief Internal flag set to true when the logger is going through the - * "testing mode" routine. - */ - static volatile bool isTestingNow; /** * @brief Internal flag set to true with then logger should begin the * "testing mode" routine when it finishes other operations. From f45c9c8f0ecebf9013023ded0b021d5977958280 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 22:50:03 -0600 Subject: [PATCH 051/138] flush log buffer immediately when test button is pushed Allows immediate transmission of data in buffer without loss before powering off and decomissioning a deployed datalogger. --- src/LoggerBase.cpp | 14 +++++++++----- src/LoggerBase.h | 4 +++- src/dataPublisherBase.cpp | 4 ++-- src/dataPublisherBase.h | 7 +++++-- src/publishers/DreamHostPublisher.cpp | 2 +- src/publishers/DreamHostPublisher.h | 3 ++- src/publishers/EnviroDIYPublisher.cpp | 7 ++++--- src/publishers/EnviroDIYPublisher.h | 3 ++- src/publishers/ThingSpeakPublisher.cpp | 2 +- src/publishers/ThingSpeakPublisher.h | 2 +- src/publishers/UbidotsPublisher.cpp | 2 +- src/publishers/UbidotsPublisher.h | 3 ++- 12 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 2238ef58c..b0a12e03d 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -349,14 +349,14 @@ bool Logger::checkRemotesConnectionNeeded(void) { return needed; } -void Logger::publishDataToRemotes(void) { +void Logger::publishDataToRemotes(bool forceFlush) { MS_DBG(F("Sending out remote data.")); for (uint8_t i = 0; i < MAX_NUMBER_SENDERS; i++) { if (dataPublishers[i] != nullptr) { PRINTOUT(F("\nSending data to ["), i, F("]"), dataPublishers[i]->getEndpoint()); - dataPublishers[i]->publishData(); + dataPublishers[i]->publishData(forceFlush); watchDogTimer.resetWatchDog(); } } @@ -1445,13 +1445,17 @@ void Logger::logDataAndPublish(bool sleepBeforeReturning) { // Create a csv data record and save it to the log file logToSD(); + // flush the publisher buffers (if any) if we have been invoked by the + // testing button + bool forceFlush = Logger::startTesting; + // Sync the clock at noon bool clockSyncNeeded = (Logger::markedLocalEpochTime != 0 && Logger::markedLocalEpochTime % 86400 == 43200) || !isRTCSane(Logger::markedLocalEpochTime); bool connectionNeeded = checkRemotesConnectionNeeded() || - clockSyncNeeded; + clockSyncNeeded || forceFlush; if (_logModem != nullptr && connectionNeeded) { MS_DBG(F("Waking up"), _logModem->getModemName(), F("...")); @@ -1462,7 +1466,7 @@ void Logger::logDataAndPublish(bool sleepBeforeReturning) { if (_logModem->connectInternet()) { // Publish data to remotes watchDogTimer.resetWatchDog(); - publishDataToRemotes(); + publishDataToRemotes(forceFlush); watchDogTimer.resetWatchDog(); if (clockSyncNeeded) { @@ -1489,7 +1493,7 @@ void Logger::logDataAndPublish(bool sleepBeforeReturning) { MS_DBG(F("Nobody needs it so publishing without connecting...")); // Call publish function without connection watchDogTimer.resetWatchDog(); - publishDataToRemotes(); + publishDataToRemotes(false); // can't flush without a connection watchDogTimer.resetWatchDog(); } diff --git a/src/LoggerBase.h b/src/LoggerBase.h index e8d5a0e4d..86fd2d0ea 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -594,8 +594,10 @@ class Logger { bool checkRemotesConnectionNeeded(void); /** * @brief Publish data to all registered data publishers. + * + * @param forceFlush Ask the publishers to flush buffered data immediately. */ - void publishDataToRemotes(void); + void publishDataToRemotes(bool forceFlush = false); /** * @brief Retained for backwards compatibility, use publishDataToRemotes() * in new code. diff --git a/src/dataPublisherBase.cpp b/src/dataPublisherBase.cpp index 0c5e5cf15..9f989c3a6 100644 --- a/src/dataPublisherBase.cpp +++ b/src/dataPublisherBase.cpp @@ -148,12 +148,12 @@ bool dataPublisher::connectionNeeded(void) { } // This sends data on the "default" client of the modem -int16_t dataPublisher::publishData() { +int16_t dataPublisher::publishData(bool forceFlush) { if (_inClient == nullptr) { PRINTOUT(F("ERROR! No web client assigned to publish data!")); return 0; } else { - return publishData(_inClient); + return publishData(_inClient, forceFlush); } } // Duplicates for backwards compatibility diff --git a/src/dataPublisherBase.h b/src/dataPublisherBase.h index ccd70ab25..9a0dea4b0 100644 --- a/src/dataPublisherBase.h +++ b/src/dataPublisherBase.h @@ -212,10 +212,11 @@ class dataPublisher { * @param outClient An Arduino client instance to use to print data to. * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance + * @param forceFlush Ask the publisher to flush buffered data immediately. * @return **int16_t** The result of publishing data. May be an http * response code or a result code from PubSubClient. */ - virtual int16_t publishData(Client* outClient) = 0; + virtual int16_t publishData(Client* outClient, bool forceFlush = false) = 0; /** * @brief Open a socket to the correct receiver and send out the formatted * data. @@ -224,10 +225,12 @@ class dataPublisher { * either a client having been linked to the publisher or a logger modem * having been linked to the logger linked to the publisher. * + * @param forceFlush Ask the publisher to flush buffered data immediately. + * * @return **int16_t** The result of publishing data. May be an http * response code or a result code from PubSubClient. */ - virtual int16_t publishData(); + virtual int16_t publishData(bool forceFlush = false); /** * @brief Retained for backwards compatibility; use publishData(Client* diff --git a/src/publishers/DreamHostPublisher.cpp b/src/publishers/DreamHostPublisher.cpp index 74412523e..116b78e08 100644 --- a/src/publishers/DreamHostPublisher.cpp +++ b/src/publishers/DreamHostPublisher.cpp @@ -64,7 +64,7 @@ void DreamHostPublisher::begin(Logger& baseLogger, const char* dhUrl) { // Post the data to dream host. // int16_t DreamHostPublisher::postDataDreamHost(void) -int16_t DreamHostPublisher::publishData(Client* outClient) { +int16_t DreamHostPublisher::publishData(Client* outClient, bool forceFlush) { // Create a buffer for the portions of the request and response char tempBuffer[37] = ""; uint16_t did_respond = 0; diff --git a/src/publishers/DreamHostPublisher.h b/src/publishers/DreamHostPublisher.h index e7a8a6fb6..b18f84db4 100644 --- a/src/publishers/DreamHostPublisher.h +++ b/src/publishers/DreamHostPublisher.h @@ -142,10 +142,11 @@ class DreamHostPublisher : public dataPublisher { * @param outClient An Arduino client instance to use to print data to. * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance + * @param forceFlush Ask the publisher to flush buffered data immediately. * * @return **int16_t** The http status code of the response. */ - int16_t publishData(Client* outClient) override; + int16_t publishData(Client* outClient, bool forceFlush = false) override; protected: // portions of the GET request diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index 280f35e38..50c907c39 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -165,11 +165,12 @@ bool EnviroDIYPublisher::connectionNeeded(void) { // EnviroDIY/ODM2DataSharingPortal and then streams out a post request // over that connection. // The return is the http status code of the response. -int16_t EnviroDIYPublisher::publishData(Client* outClient) { - // do we intend to send this call? if so, we have just returned true from +int16_t EnviroDIYPublisher::publishData(Client* outClient, bool forceFlush) { + // do we intend to flush this call? if so, we have just returned true from // connectionNeeded() and the internet is connected and waiting. check what // that function said so we know to do it after we record this data point. - bool willFlush = connectionNeeded(); + // we also flush if requested (in which case the internet is connected too) + bool willFlush = connectionNeeded() || forceFlush; // create record to hold timestamp and variable values in the log buffer int record = _logBuffer.addRecord(Logger::markedLocalEpochTime); diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index b984f08c1..a9917eb92 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -178,9 +178,10 @@ class EnviroDIYPublisher : public dataPublisher { * @param outClient An Arduino client instance to use to print data to. * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance + * @param forceFlush Ask the publisher to flush buffered data immediately. * @return **int16_t** The http status code of the response. */ - int16_t publishData(Client* outClient) override; + int16_t publishData(Client* outClient, bool forceFlush = false) override; protected: /** diff --git a/src/publishers/ThingSpeakPublisher.cpp b/src/publishers/ThingSpeakPublisher.cpp index a00e3c3e7..8d32afd28 100644 --- a/src/publishers/ThingSpeakPublisher.cpp +++ b/src/publishers/ThingSpeakPublisher.cpp @@ -101,7 +101,7 @@ void ThingSpeakPublisher::begin(Logger& baseLogger, // This sends the data to ThingSpeak // bool ThingSpeakPublisher::mqttThingSpeak(void) -int16_t ThingSpeakPublisher::publishData(Client* outClient) { +int16_t ThingSpeakPublisher::publishData(Client* outClient, bool forceFlush) { bool retVal = false; // Make sure we don't have too many fields diff --git a/src/publishers/ThingSpeakPublisher.h b/src/publishers/ThingSpeakPublisher.h index e61b9ec49..4de3e6ed3 100644 --- a/src/publishers/ThingSpeakPublisher.h +++ b/src/publishers/ThingSpeakPublisher.h @@ -197,7 +197,7 @@ class ThingSpeakPublisher : public dataPublisher { // This sends the data to ThingSpeak // bool mqttThingSpeak(void); - int16_t publishData(Client* outClient) override; + int16_t publishData(Client* outClient, bool forceFlush = false) override; protected: /** diff --git a/src/publishers/UbidotsPublisher.cpp b/src/publishers/UbidotsPublisher.cpp index 5477345a4..7e38ede3e 100644 --- a/src/publishers/UbidotsPublisher.cpp +++ b/src/publishers/UbidotsPublisher.cpp @@ -112,7 +112,7 @@ void UbidotsPublisher::begin(Logger& baseLogger, // over that connection. // The return is the http status code of the response. // int16_t EnviroDIYPublisher::postDataEnviroDIY(void) -int16_t UbidotsPublisher::publishData(Client* outClient) { +int16_t UbidotsPublisher::publishData(Client* outClient, bool forceFlush) { // Create a buffer for the portions of the request and response char tempBuffer[37] = ""; uint16_t did_respond = 0; diff --git a/src/publishers/UbidotsPublisher.h b/src/publishers/UbidotsPublisher.h index 94853c79a..ca4882f72 100644 --- a/src/publishers/UbidotsPublisher.h +++ b/src/publishers/UbidotsPublisher.h @@ -175,9 +175,10 @@ class UbidotsPublisher : public dataPublisher { * @param outClient An Arduino client instance to use to print data to. * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance + * @param forceFlush Ask the publisher to flush buffered data immediately. * @return **int16_t** The http status code of the response. */ - int16_t publishData(Client* outClient) override; + int16_t publishData(Client* outClient, bool forceFlush) override; protected: /** From 5b6bd1c13eb988afa38d377a5b562b8ff786a2df Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 9 Feb 2023 22:58:35 -0600 Subject: [PATCH 052/138] remove hearsay about logger construction order The C++ standard specifies that all objects in the same translation unit (i.e. source file) are constructed in order of declaration. Since this is the most common case when using Modular Sensors, the described case cannot occur. --- src/dataPublisherBase.h | 28 ++-------------------------- src/publishers/DreamHostPublisher.h | 12 ------------ src/publishers/EnviroDIYPublisher.h | 12 ------------ src/publishers/ThingSpeakPublisher.h | 12 ------------ src/publishers/UbidotsPublisher.h | 12 ------------ 5 files changed, 2 insertions(+), 74 deletions(-) diff --git a/src/dataPublisherBase.h b/src/dataPublisherBase.h index 9a0dea4b0..6fd94bce6 100644 --- a/src/dataPublisherBase.h +++ b/src/dataPublisherBase.h @@ -87,12 +87,6 @@ class dataPublisher { * @param baseLogger The logger supplying the data to be published * @param sendEveryX Interval (in units of the logging interval) between * attempted data transmissions. Not respected by all publishers. - * - * @note It is possible (though very unlikey) that using this constructor - * could cause errors if the compiler attempts to initialize the publisher - * instance before the logger instance. If you suspect you are seeing that - * issue, use the null constructor and a populated begin(...) within your - * set-up function. */ explicit dataPublisher(Logger& baseLogger, int sendEveryX = 1); /** @@ -104,12 +98,6 @@ class dataPublisher { * single TinyGSM modem instance * @param sendEveryX Interval (in units of the logging interval) between * attempted data transmissions. Not respected by all publishers. - * - * @note It is possible (though very unlikey) that using this constructor - * could cause errors if the compiler attempts to initialize the publisher - * instance before the logger instance. If you suspect you are seeing that - * issue, use the null constructor and a populated begin(...) within your - * set-up function. */ dataPublisher(Logger& baseLogger, Client* inClient, int sendEveryX = 1); /** @@ -148,13 +136,7 @@ class dataPublisher { * @brief Begin the publisher - linking it to the client and logger. * * This can be used as an alternative to adding the logger and client in the - * constructor. This is slightly "safer" because we expect the publishers - * to be created in the "global scope" and we cannot control the order in - * which objects in that global scope will be created. That is, we cannot - * guarantee that the logger will actually be created before the publisher - * that wants to attach to it unless we wait to attach the publisher until - * in the setup or loop function of the main program. In reality, it is - * very unlikely that this is necessary. + * constructor. * * @param baseLogger The logger supplying the data to be published * @param inClient An Arduino client instance to use to print data to. @@ -172,13 +154,7 @@ class dataPublisher { * logger. * * This can be used as an alternative to adding the logger and client in the - * constructor. This is slightly "safer" because we expect the publishers - * to be created in the "global scope" and we cannot control the order in - * which objects in that global scope will be created. That is, we cannot - * guarantee that the logger will actually be created before the publisher - * that wants to attach to it unless we wait to attach the publisher until - * in the setup or loop function of the main program. In reality, it is - * very unlikely that this is necessary. + * constructor. * * @param baseLogger The logger supplying the data to be published */ diff --git a/src/publishers/DreamHostPublisher.h b/src/publishers/DreamHostPublisher.h index b18f84db4..ade9b69c8 100644 --- a/src/publishers/DreamHostPublisher.h +++ b/src/publishers/DreamHostPublisher.h @@ -53,12 +53,6 @@ class DreamHostPublisher : public dataPublisher { * @param baseLogger The logger supplying the data to be published * @param sendEveryX Interval (in units of the logging interval) between * attempted data transmissions. NOTE: not implemented by this publisher! - * - * @note It is possible (though very unlikey) that using this constructor - * could cause errors if the compiler attempts to initialize the publisher - * instance before the logger instance. If you suspect you are seeing that - * issue, use the null constructor and a populated begin(...) within your - * set-up function. */ explicit DreamHostPublisher(Logger& baseLogger, int sendEveryX = 1); /** @@ -70,12 +64,6 @@ class DreamHostPublisher : public dataPublisher { * single TinyGSM modem instance * @param sendEveryX Interval (in units of the logging interval) between * attempted data transmissions. NOTE: not implemented by this publisher! - * - * @note It is possible (though very unlikey) that using this constructor - * could cause errors if the compiler attempts to initialize the publisher - * instance before the logger instance. If you suspect you are seeing that - * issue, use the null constructor and a populated begin(...) within your - * set-up function. */ DreamHostPublisher(Logger& baseLogger, Client* inClient, int sendEveryX = 1); diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index a9917eb92..6f4221e70 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -56,12 +56,6 @@ class EnviroDIYPublisher : public dataPublisher { * @param baseLogger The logger supplying the data to be published * @param sendEveryX Interval (in units of the logging interval) between * attempted data transmissions. - * - * @note It is possible (though very unlikey) that using this constructor - * could cause errors if the compiler attempts to initialize the publisher - * instance before the logger instance. If you suspect you are seeing that - * issue, use the null constructor and a populated begin(...) within your - * set-up function. */ explicit EnviroDIYPublisher(Logger& baseLogger, int sendEveryX = 1); /** @@ -73,12 +67,6 @@ class EnviroDIYPublisher : public dataPublisher { * single TinyGSM modem instance * @param sendEveryX Interval (in units of the logging interval) between * attempted data transmissions. - * - * @note It is possible (though very unlikey) that using this constructor - * could cause errors if the compiler attempts to initialize the publisher - * instance before the logger instance. If you suspect you are seeing that - * issue, use the null constructor and a populated begin(...) within your - * set-up function. */ EnviroDIYPublisher(Logger& baseLogger, Client* inClient, int sendEveryX = 1); diff --git a/src/publishers/ThingSpeakPublisher.h b/src/publishers/ThingSpeakPublisher.h index 4de3e6ed3..55d5394ae 100644 --- a/src/publishers/ThingSpeakPublisher.h +++ b/src/publishers/ThingSpeakPublisher.h @@ -78,12 +78,6 @@ class ThingSpeakPublisher : public dataPublisher { * @param baseLogger The logger supplying the data to be published * @param sendEveryX Interval (in units of the logging interval) between * attempted data transmissions. NOTE: not implemented by this publisher! - * - * @note It is possible (though very unlikey) that using this constructor - * could cause errors if the compiler attempts to initialize the publisher - * instance before the logger instance. If you suspect you are seeing that - * issue, use the null constructor and a populated begin(...) within your - * set-up function. */ explicit ThingSpeakPublisher(Logger& baseLogger, int sendEveryX = 1); /** @@ -95,12 +89,6 @@ class ThingSpeakPublisher : public dataPublisher { * single TinyGSM modem instance * @param sendEveryX Interval (in units of the logging interval) between * attempted data transmissions. NOTE: not implemented by this publisher! - * - * @note It is possible (though very unlikey) that using this constructor - * could cause errors if the compiler attempts to initialize the publisher - * instance before the logger instance. If you suspect you are seeing that - * issue, use the null constructor and a populated begin(...) within your - * set-up function. */ ThingSpeakPublisher(Logger& baseLogger, Client* inClient, int sendEveryX = 1); diff --git a/src/publishers/UbidotsPublisher.h b/src/publishers/UbidotsPublisher.h index ca4882f72..0f764514b 100644 --- a/src/publishers/UbidotsPublisher.h +++ b/src/publishers/UbidotsPublisher.h @@ -52,12 +52,6 @@ class UbidotsPublisher : public dataPublisher { * @param baseLogger The logger supplying the data to be published * @param sendEveryX Interval (in units of the logging interval) between * attempted data transmissions. NOTE: not implemented by this publisher! - * - * @note It is possible (though very unlikey) that using this constructor - * could cause errors if the compiler attempts to initialize the publisher - * instance before the logger instance. If you suspect you are seeing that - * issue, use the null constructor and a populated begin(...) within your - * set-up function. */ explicit UbidotsPublisher(Logger& baseLogger, int sendEveryX = 1); /** @@ -69,12 +63,6 @@ class UbidotsPublisher : public dataPublisher { * single TinyGSM modem instance * @param sendEveryX Interval (in units of the logging interval) between * attempted data transmissions. NOTE: not implemented by this publisher! - * - * @note It is possible (though very unlikey) that using this constructor - * could cause errors if the compiler attempts to initialize the publisher - * instance before the logger instance. If you suspect you are seeing that - * issue, use the null constructor and a populated begin(...) within your - * set-up function. */ UbidotsPublisher(Logger& baseLogger, Client* inClient, int sendEveryX = 1); /** From d7c1970d0371249f908d9481117dca4ffe33ff52 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Fri, 10 Feb 2023 08:27:33 -0600 Subject: [PATCH 053/138] LoggerBase: increase connection timeout when publishing Towers seem to take longer to connect the less recently a connection has been estasblished. Now that that's been expanded from 15 minutes to 8 hours, increase the timeout for that action to 4 minutes from 50 seconds. --- src/LoggerBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index b0a12e03d..b79434d0e 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -1463,7 +1463,7 @@ void Logger::logDataAndPublish(bool sleepBeforeReturning) { // Connect to the network watchDogTimer.resetWatchDog(); MS_DBG(F("Connecting to the Internet...")); - if (_logModem->connectInternet()) { + if (_logModem->connectInternet(240000L)) { // Publish data to remotes watchDogTimer.resetWatchDog(); publishDataToRemotes(forceFlush); From ad6c41d8c495d90fc636928c13ee0437545fa68b Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 16 Mar 2023 11:18:47 -0500 Subject: [PATCH 054/138] publishers/ThingSpeakPublisher: fix buffer append order --- src/publishers/ThingSpeakPublisher.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/publishers/ThingSpeakPublisher.cpp b/src/publishers/ThingSpeakPublisher.cpp index 8d32afd28..ad04c374e 100644 --- a/src/publishers/ThingSpeakPublisher.cpp +++ b/src/publishers/ThingSpeakPublisher.cpp @@ -131,13 +131,12 @@ int16_t ThingSpeakPublisher::publishData(Client* outClient, bool forceFlush) { // buffer is used only locally, it does not transmit txBufferInit(nullptr); + txBufferAppend("created_at="); txBufferAppend(Logger::formatDateTime_ISO8601( Logger::markedLocalEpochTime).c_str()); - txBufferAppend("created_at="); for (uint8_t i = 0; i < numChannels; i++) { - txBufferAppend('&'); - txBufferAppend("field"); + txBufferAppend("&field"); itoa(i + 1, tempBuffer, 10); // BASE 10 txBufferAppend(tempBuffer); txBufferAppend('='); From 0df76186020fae6394aedeaf927e631f42686eb1 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 16 Mar 2023 14:43:23 -0500 Subject: [PATCH 055/138] libraries/ModularSensors: run clang-format on *.cpp and *.h --- src/LogBuffer.cpp | 4 ++-- src/LoggerBase.cpp | 7 +++---- src/dataPublisherBase.cpp | 6 +++--- src/modems/LoggerModemMacros.h | 3 ++- src/publishers/EnviroDIYPublisher.cpp | 10 +++++----- src/publishers/ThingSpeakPublisher.cpp | 8 ++++---- src/sensors/DwyerSBLT2.cpp | 17 ++++++++++------- src/sensors/DwyerSBLT2.h | 24 ++++++++++++------------ 8 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/LogBuffer.cpp b/src/LogBuffer.cpp index 46c05ef56..b79b51edf 100644 --- a/src/LogBuffer.cpp +++ b/src/LogBuffer.cpp @@ -41,10 +41,10 @@ int LogBuffer::getNumRecords(void) { } uint8_t LogBuffer::getPercentFull(void) { - uint32_t bytesFull = (uint32_t)numRecords * (uint32_t)recordSize; + uint32_t bytesFull = (uint32_t)numRecords * (uint32_t)recordSize; uint32_t bytesTotal = MS_LOG_DATA_BUFFER_SIZE; - return (uint8_t)((bytesFull*(uint32_t)100)/bytesTotal); + return (uint8_t)((bytesFull * (uint32_t)100) / bytesTotal); } int LogBuffer::addRecord(uint32_t timestamp) { diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index b79434d0e..7c1e0ab8d 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -598,7 +598,7 @@ void Logger::markTime(void) { bool Logger::checkInterval(void) { bool retval; uint32_t checkTime = getNowLocalEpoch(); - uint16_t interval = _loggingIntervalMinutes; + uint16_t interval = _loggingIntervalMinutes; if (_initialShortIntervals > 0) { // log the first few samples at an interval of 1 minute so that // operation can be quickly verified in the field @@ -609,8 +609,7 @@ bool Logger::checkInterval(void) { MS_DBG(F("Current Unix Timestamp:"), checkTime, F("->"), formatDateTime_ISO8601(checkTime)); MS_DBG(F("Logging interval in seconds:"), (interval * 60)); - MS_DBG(F("Mod of Logging Interval:"), - checkTime % (interval * 60)); + MS_DBG(F("Mod of Logging Interval:"), checkTime % (interval * 60)); if ((checkTime % (interval * 60) == 0) || Logger::startTesting) { // Update the time variables with the current time @@ -1493,7 +1492,7 @@ void Logger::logDataAndPublish(bool sleepBeforeReturning) { MS_DBG(F("Nobody needs it so publishing without connecting...")); // Call publish function without connection watchDogTimer.resetWatchDog(); - publishDataToRemotes(false); // can't flush without a connection + publishDataToRemotes(false); // can't flush without a connection watchDogTimer.resetWatchDog(); } diff --git a/src/dataPublisherBase.cpp b/src/dataPublisherBase.cpp index 9f989c3a6..46d7a4079 100644 --- a/src/dataPublisherBase.cpp +++ b/src/dataPublisherBase.cpp @@ -112,8 +112,8 @@ void dataPublisher::txBufferFlush() { STANDARD_SERIAL_OUTPUT.flush(); #endif - uint8_t tries = 10; - const uint8_t* ptr = (const uint8_t*)txBuffer; + uint8_t tries = 10; + const uint8_t* ptr = (const uint8_t*)txBuffer; while (true) { size_t sent = txBufferOutClient->write(ptr, txBufferLen); txBufferLen -= sent; @@ -133,7 +133,7 @@ void dataPublisher::txBufferFlush() { // the connection now so it will get reset and we can try to // transmit the data again later txBufferOutClient = nullptr; - txBufferLen = 0; + txBufferLen = 0; return; } diff --git a/src/modems/LoggerModemMacros.h b/src/modems/LoggerModemMacros.h index bb04f7693..0036d4854 100644 --- a/src/modems/LoggerModemMacros.h +++ b/src/modems/LoggerModemMacros.h @@ -468,7 +468,8 @@ \ /** Try up to 12 times to get a timestamp from NIST. */ \ for (uint8_t i = 0; i < 12; i++) { \ - while (millis() < _lastNISTrequest + 4000) { /* wait */ } \ + while (millis() < _lastNISTrequest + 4000) { /* wait */ \ + } \ \ /** Make TCP connection. */ \ MS_DBG(F("\nConnecting to NIST daytime Server")); \ diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index 50c907c39..3dd49dc78 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -42,7 +42,7 @@ EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, Client* inClient, EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, const char* registrationToken, const char* samplingFeatureUUID, - int sendEveryX) + int sendEveryX) : dataPublisher(baseLogger, sendEveryX) { setToken(registrationToken); _baseLogger->setSamplingFeatureUUID(samplingFeatureUUID); @@ -51,7 +51,7 @@ EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, Client* inClient, const char* registrationToken, const char* samplingFeatureUUID, - int sendEveryX) + int sendEveryX) : dataPublisher(baseLogger, inClient, sendEveryX) { setToken(registrationToken); _baseLogger->setSamplingFeatureUUID(samplingFeatureUUID); @@ -121,8 +121,8 @@ void EnviroDIYPublisher::begin(Logger& baseLogger, bool EnviroDIYPublisher::connectionNeeded(void) { // compute the send interval, reducing it as the buffer gets more full so we // have less of a chance of losing data - int interval = _sendEveryX; - uint8_t percent = _logBuffer.getPercentFull(); + int interval = _sendEveryX; + uint8_t percent = _logBuffer.getPercentFull(); if (percent >= 50) { interval /= 2; } else if (percent >= 75) { @@ -143,7 +143,7 @@ bool EnviroDIYPublisher::connectionNeeded(void) { if (relative == (interval - 1)) { // the next sample will put us right at the interval atSendInterval = true; - } else if (numRecords >= interval) { // don't send the first sample + } else if (numRecords >= interval) { // don't send the first sample if (relative == 0) { // the last sample was the interval, this is the first retry atSendInterval = true; diff --git a/src/publishers/ThingSpeakPublisher.cpp b/src/publishers/ThingSpeakPublisher.cpp index ad04c374e..fa629c495 100644 --- a/src/publishers/ThingSpeakPublisher.cpp +++ b/src/publishers/ThingSpeakPublisher.cpp @@ -34,7 +34,7 @@ ThingSpeakPublisher::ThingSpeakPublisher(Logger& baseLogger, const char* thingSpeakMQTTKey, const char* thingSpeakChannelID, const char* thingSpeakChannelKey, - int sendEveryX) + int sendEveryX) : dataPublisher(baseLogger, sendEveryX) { setMQTTKey(thingSpeakMQTTKey); setChannelID(thingSpeakChannelID); @@ -44,7 +44,7 @@ ThingSpeakPublisher::ThingSpeakPublisher(Logger& baseLogger, Client* inClient, const char* thingSpeakMQTTKey, const char* thingSpeakChannelID, const char* thingSpeakChannelKey, - int sendEveryX) + int sendEveryX) : dataPublisher(baseLogger, inClient, sendEveryX) { setMQTTKey(thingSpeakMQTTKey); setChannelID(thingSpeakChannelID); @@ -132,8 +132,8 @@ int16_t ThingSpeakPublisher::publishData(Client* outClient, bool forceFlush) { txBufferInit(nullptr); txBufferAppend("created_at="); - txBufferAppend(Logger::formatDateTime_ISO8601( - Logger::markedLocalEpochTime).c_str()); + txBufferAppend( + Logger::formatDateTime_ISO8601(Logger::markedLocalEpochTime).c_str()); for (uint8_t i = 0; i < numChannels; i++) { txBufferAppend("&field"); diff --git a/src/sensors/DwyerSBLT2.cpp b/src/sensors/DwyerSBLT2.cpp index 0c3a040fe..3a66e7203 100644 --- a/src/sensors/DwyerSBLT2.cpp +++ b/src/sensors/DwyerSBLT2.cpp @@ -13,11 +13,12 @@ // The constructor - need the power pin, the data pin, and the calibration info -DwyerSBLT2::DwyerSBLT2(int8_t powerPin, uint8_t adsChannel, float conversion_coefficient, float conversion_constant, - uint8_t i2cAddress, uint8_t measurementsToAverage) +DwyerSBLT2::DwyerSBLT2(int8_t powerPin, uint8_t adsChannel, + float conversion_coefficient, float conversion_constant, + uint8_t i2cAddress, uint8_t measurementsToAverage) : Sensor("DwyerSBLT2", SBLT2_NUM_VARIABLES, SBLT2_WARM_UP_TIME_MS, - SBLT2_STABILIZATION_TIME_MS, SBLT2_MEASUREMENT_TIME_MS, powerPin, -1, - measurementsToAverage, SBLT2_INC_CALC_VARIABLES), + SBLT2_STABILIZATION_TIME_MS, SBLT2_MEASUREMENT_TIME_MS, powerPin, + -1, measurementsToAverage, SBLT2_INC_CALC_VARIABLES), _adsChannel(adsChannel), _conversion_coefficient(conversion_coefficient), _conversion_constant(conversion_constant), @@ -74,7 +75,8 @@ bool DwyerSBLT2::addSingleMeasurementResult(void) { ads.begin(); // Print out the calibration curve - MS_DBG(F(" Input calibration Curve:"), _conversion_coefficient, F("x +"), _conversion_constant); + MS_DBG(F(" Input calibration Curve:"), _conversion_coefficient, + F("x +"), _conversion_constant); // Read Analog to Digital Converter (ADC) // Taking this reading includes the 8ms conversion delay. @@ -88,11 +90,12 @@ bool DwyerSBLT2::addSingleMeasurementResult(void) { if (adcVoltage < 5.0 && adcVoltage > -0.3) { // Skip results out of range // Apply the unique calibration curve for the given sensor - calibResult = ((_conversion_coefficient * adcVoltage) - _conversion_constant)/1000; + calibResult = ((_conversion_coefficient * adcVoltage) - + _conversion_constant) / + 1000; MS_DBG(F(" calibResult:"), calibResult); } else { // set invalid voltages back to -9999 adcVoltage = -9999; - } } else { MS_DBG(getSensorNameAndLocation(), F("is not currently measuring!")); diff --git a/src/sensors/DwyerSBLT2.h b/src/sensors/DwyerSBLT2.h index 1547e9550..be8a61e0f 100644 --- a/src/sensors/DwyerSBLT2.h +++ b/src/sensors/DwyerSBLT2.h @@ -85,7 +85,8 @@ /** @ingroup sensor_obs3 */ /**@{*/ /** - * @brief Sensor::_numReturnedValues; the SBLT2 will return raw voltage which will be converted into depth(m). + * @brief Sensor::_numReturnedValues; the SBLT2 will return raw voltage which + * will be converted into depth(m). */ #define SBLT2_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; depth is calculated from raw voltage @@ -104,7 +105,7 @@ /// OBS3 is 2s (2000ms). #define SBLT2_STABILIZATION_TIME_MS 2000 /// @brief Sensor::_measurementTime_ms; OBS3 takes 100ms to complete a -/// measurement - Maximum data rate = 10Hz (100ms/sample). +/// measurement - Maximum data rate = 10Hz (100ms/sample). ///#FIXME look to update to 50ms which is SLTB2 reported response time #define SBLT2_MEASUREMENT_TIME_MS 100 /**@}*/ @@ -245,10 +246,10 @@ class DwyerSBLT2 : public Sensor { * average before giving a "final" result from the sensor; optional with a * default value of 1. */ - DwyerSBLT2(int8_t powerPin, uint8_t adsChannel, float conversion_coefficient, - float conversion_constant, - uint8_t i2cAddress = ADS1115_ADDRESS, - uint8_t measurementsToAverage = 1); + DwyerSBLT2(int8_t powerPin, uint8_t adsChannel, + float conversion_coefficient, float conversion_constant, + uint8_t i2cAddress = ADS1115_ADDRESS, + uint8_t measurementsToAverage = 1); /** * @brief Destroy the Dwyer SBLT2 object */ @@ -295,9 +296,8 @@ class DwyerSBLT2_Depth : public Variable { * @param varCode A short code to help identify the variable in files; * optional with a default value of "OBS3Turbidity". */ - explicit DwyerSBLT2_Depth( - DwyerSBLT2* parentSense, const char* uuid = "", - const char* varCode = SBLT2_DEPTH_DEFAULT_CODE) + explicit DwyerSBLT2_Depth(DwyerSBLT2* parentSense, const char* uuid = "", + const char* varCode = SBLT2_DEPTH_DEFAULT_CODE) : Variable(parentSense, (const uint8_t)SBLT2_DEPTH_VAR_NUM, (uint8_t)SBLT2_RESOLUTION, SBLT2_DEPTH_VAR_NAME, SBLT2_DEPTH_UNIT_NAME, varCode, uuid) {} @@ -307,9 +307,9 @@ class DwyerSBLT2_Depth : public Variable { * @note This must be tied with a parent CampbellOBS3 before it can be used. */ DwyerSBLT2_Depth() - : Variable((const uint8_t)SBLT2_DEPTH_VAR_NUM, (uint8_t)SBLT2_RESOLUTION, - SBLT2_DEPTH_VAR_NAME, SBLT2_DEPTH_UNIT_NAME, - SBLT2_DEPTH_DEFAULT_CODE) {} + : Variable((const uint8_t)SBLT2_DEPTH_VAR_NUM, + (uint8_t)SBLT2_RESOLUTION, SBLT2_DEPTH_VAR_NAME, + SBLT2_DEPTH_UNIT_NAME, SBLT2_DEPTH_DEFAULT_CODE) {} ~DwyerSBLT2_Depth() {} }; From 6a30577fcad39f516a49df42e256afa8d9c9ed2c Mon Sep 17 00:00:00 2001 From: brmiller1 <117111930+brmiller1@users.noreply.github.com> Date: Wed, 5 Apr 2023 11:54:03 -0500 Subject: [PATCH 056/138] Merge pull request #4 from JacobsSensorLab/MaxbotixAddition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modification to Maxbotix main, config template and library to be conf… --- src/sensors/MaxBotixSonar.cpp | 41 +++++++++++++++++++++-------------- src/sensors/MaxBotixSonar.h | 24 +++++++++++++------- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/sensors/MaxBotixSonar.cpp b/src/sensors/MaxBotixSonar.cpp index 7c3b1fa62..b096063ff 100644 --- a/src/sensors/MaxBotixSonar.cpp +++ b/src/sensors/MaxBotixSonar.cpp @@ -10,20 +10,27 @@ #include "MaxBotixSonar.h" -MaxBotixSonar::MaxBotixSonar(Stream* stream, int8_t powerPin, int8_t triggerPin, - uint8_t measurementsToAverage) +MaxBotixSonar::MaxBotixSonar(Stream* stream, int8_t powerPin, int16_t maxRange, int8_t triggerPin, + uint8_t measurementsToAverage, bool convertCm) : Sensor("MaxBotixMaxSonar", HRXL_NUM_VARIABLES, HRXL_WARM_UP_TIME_MS, HRXL_STABILIZATION_TIME_MS, HRXL_MEASUREMENT_TIME_MS, powerPin, -1, measurementsToAverage), + _maxRange(maxRange), _triggerPin(triggerPin), + _convertCm(convertCm), _stream(stream) {} -MaxBotixSonar::MaxBotixSonar(Stream& stream, int8_t powerPin, int8_t triggerPin, - uint8_t measurementsToAverage) + + +MaxBotixSonar::MaxBotixSonar(Stream& stream, int8_t powerPin, int16_t maxRange, int8_t triggerPin, + uint8_t measurementsToAverage, bool convertCm) : Sensor("MaxBotixMaxSonar", HRXL_NUM_VARIABLES, HRXL_WARM_UP_TIME_MS, HRXL_STABILIZATION_TIME_MS, HRXL_MEASUREMENT_TIME_MS, powerPin, -1, measurementsToAverage, HRXL_INC_CALC_VARIABLES), + _maxRange(maxRange), _triggerPin(triggerPin), + _convertCm(convertCm), _stream(&stream) {} + // Destructor MaxBotixSonar::~MaxBotixSonar() {} @@ -44,8 +51,8 @@ bool MaxBotixSonar::setup(void) { } // Set the stream timeout - // Even the slowest sensors should respond at a rate of 6Hz (166ms). - _stream->setTimeout(180); + // Even the slowest sensors should respond at a rate of 4Hz (250ms). + _stream->setTimeout(250); return Sensor::setup(); // this will set pin modes and the setup status bit } @@ -141,21 +148,23 @@ bool MaxBotixSonar::addSingleMeasurementResult(void) { _stream->read(); // To throw away the carriage return MS_DBG(F(" Sonar Range:"), result); rangeAttempts++; - - // If it cannot obtain a result , the sonar is supposed to send a - // value just above it's max range. For our 7m model, this is 765. - // If the result becomes garbled or the sonar is - // disconnected, the parseInt function returns 0. Luckily, these - // sensors are not capable of reading 0, so we also know the 0 value - // is bad. - if (result <= 0 || result >= 765) { + + + // If it cannot obtain a result, the sonar is supposed to send a + // value just above its max range. If the result becomes garbled or + // the sonar is disconnected, the parseInt function returns 0. + // Luckily, these sensors are not capable of reading 0, so we also + // know the 0 value is bad. + if (result <= 0 || result >= _maxRange) { MS_DBG(F(" Bad or Suspicious Result, Retry Attempt #"), rangeAttempts); result = -9999; } else { MS_DBG(F(" Good result found")); - // convert result from cm to mm - result *= 10; + // convert result from cm to mm if convertCm is set to true + if (_convertCm == true) { + result *= 10; + } success = true; } } diff --git a/src/sensors/MaxBotixSonar.h b/src/sensors/MaxBotixSonar.h index 676886f6f..7b3077e05 100644 --- a/src/sensors/MaxBotixSonar.h +++ b/src/sensors/MaxBotixSonar.h @@ -128,27 +128,27 @@ */ /**@{*/ /// @brief Sensor::_warmUpTime_ms; warm up time to completion of header: 160ms. -#define HRXL_WARM_UP_TIME_MS 160 +#define HRXL_WARM_UP_TIME_MS 250 /// @brief Sensor::_stabilizationTime_ms; the HRXL is stable as soon as it warms /// up (0ms stabilization). #define HRXL_STABILIZATION_TIME_MS 0 /// @brief Sensor::_measurementTime_ms; the HRXL takes 166ms to complete a /// measurement. -#define HRXL_MEASUREMENT_TIME_MS 166 +#define HRXL_MEASUREMENT_TIME_MS 250 /**@}*/ /** * @anchor sensor_maxbotix_range * @name Range * The range variable from a Maxbotix HRXL ultrasonic range finder - * - Range is 300 to 5000mm or 500 to 9999mm, depending on model + * - Range depends on the exact model * - Accuracy is ±1% * * {{ @ref MaxBotixSonar_Range::MaxBotixSonar_Range }} */ /**@{*/ /// @brief Decimals places in string representation; range should have 0 - -/// resolution is 1mm. +/// resolution is 1mm (except for models which have range 10mm). #define HRXL_RESOLUTION 0 /// @brief Sensor variable number; range is stored in sensorValues[0]. #define HRXL_VAR_NUM 0 @@ -183,20 +183,26 @@ class MaxBotixSonar : public Sensor { * can be used. * @param powerPin The pin on the mcu controlling power to the MaxSonar. * Use -1 if it is continuously powered. + * @param maxRange Maximum valid measurement reported by the specific sensor + * model (e.g. 5000 or 9999 or 765). * - The MaxSonar requires a 2.7V - 5.5V power supply. * @param triggerPin The pin on the mcu controlling the "trigger" for the * MaxSonar. Use -1 or omit for continuous ranging. * @param measurementsToAverage The number of measurements to take and * average before giving a "final" result from the sensor; optional with a * default value of 1. + * @param convertCm Convert centimeter range data from certain models to + * millimeters. Default false. */ - MaxBotixSonar(Stream* stream, int8_t powerPin, int8_t triggerPin = -1, - uint8_t measurementsToAverage = 1); + MaxBotixSonar(Stream* stream, int8_t powerPin, int16_t maxRange, + int8_t triggerPin = -1, uint8_t measurementsToAverage = 1, + bool convertCm = false); /** * @copydoc MaxBotixSonar::MaxBotixSonar */ - MaxBotixSonar(Stream& stream, int8_t powerPin, int8_t triggerPin = -1, - uint8_t measurementsToAverage = 1); + MaxBotixSonar(Stream& stream, int8_t powerPin, int16_t maxRange, + int8_t triggerPin = -1, uint8_t measurementsToAverage = 1, + bool convertCm = false); /** * @brief Destroy the MaxBotix Sonar object */ @@ -240,7 +246,9 @@ class MaxBotixSonar : public Sensor { bool addSingleMeasurementResult(void) override; private: + int16_t _maxRange; int8_t _triggerPin; + bool _convertCm; Stream* _stream; }; From fde0f8322e42c3bc2743e86925afc4871325316a Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 15 Sep 2023 11:39:07 -0400 Subject: [PATCH 057/138] Added begin. Can't figure out why needed. Signed-off-by: Sara Damiano --- .../DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino | 2 ++ src/LoggerBase.cpp | 8 ++++++++ src/publishers/EnviroDIYPublisher.cpp | 19 ++++++++++++++----- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino b/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino index 90742932d..d1c315e45 100644 --- a/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino +++ b/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino @@ -317,6 +317,8 @@ void setup() { // Begin the logger dataLogger.begin(); + EnviroDIYPOST.begin(dataLogger, &modem.gsmClient, registrationToken, + samplingFeature); // Note: Please change these battery voltages to match your battery // Set up the sensors, except at lowest battery level diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index dd5908ec5..500d60d28 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -1346,6 +1346,14 @@ void Logger::begin() { PRINTOUT(F("Sampling feature UUID is:"), _samplingFeatureUUID); } + + for (uint8_t i = 0; i < MAX_NUMBER_SENDERS; i++) { + if (dataPublishers[i] != nullptr) { + PRINTOUT(F("Data will be published to ["), i, F("]"), + dataPublishers[i]->getEndpoint()); + } + } + PRINTOUT(F("Logger portion of setup finished.\n")); } diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index 3dd49dc78..a4e4ce023 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -21,7 +21,7 @@ LogBuffer EnviroDIYPublisher::_logBuffer; // I want to refer to these more than once while ensuring there is only one copy // in memory const char* EnviroDIYPublisher::postEndpoint = "/api/data-stream/"; -const char* EnviroDIYPublisher::enviroDIYHost = ""; +const char* EnviroDIYPublisher::enviroDIYHost = "data.envirodiy.org"; const int EnviroDIYPublisher::enviroDIYPort = 80; const char* EnviroDIYPublisher::tokenHeader = "\r\nTOKEN: "; const char* EnviroDIYPublisher::contentLengthHeader = "\r\nContent-Length: "; @@ -35,10 +35,14 @@ const char* EnviroDIYPublisher::timestampTag = "\",\"timestamp\":["; // Constructors EnviroDIYPublisher::EnviroDIYPublisher() : dataPublisher() {} EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, int sendEveryX) - : dataPublisher(baseLogger, sendEveryX) {} + : dataPublisher(baseLogger, sendEveryX) { + _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); +} EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, Client* inClient, int sendEveryX) - : dataPublisher(baseLogger, inClient, sendEveryX) {} + : dataPublisher(baseLogger, inClient, sendEveryX) { + _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); +} EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, const char* registrationToken, const char* samplingFeatureUUID, @@ -70,6 +74,10 @@ void EnviroDIYPublisher::setToken(const char* registrationToken) { uint16_t EnviroDIYPublisher::calculateJsonSize() { uint8_t variables = _logBuffer.getNumVariables(); int records = _logBuffer.getNumRecords(); + MS_DBG(F("Number of records in log buffer:"), records); + MS_DBG(F("Number of variables in log buffer:"), variables); + MS_DBG(F("Number of variables in base logger:"), + _baseLogger->getArrayVarCount()); uint16_t jsonLength = strlen(samplingFeatureTag); jsonLength += 36; // sampling feature UUID @@ -95,6 +103,7 @@ uint16_t EnviroDIYPublisher::calculateJsonSize() { } } jsonLength += 1; // } + MS_DBG(F("Outgoing JSON size:"), jsonLength); return jsonLength; } @@ -123,6 +132,7 @@ bool EnviroDIYPublisher::connectionNeeded(void) { // have less of a chance of losing data int interval = _sendEveryX; uint8_t percent = _logBuffer.getPercentFull(); + MS_DBG(F("Buffer is"), percent, F("percent full")); if (percent >= 50) { interval /= 2; } else if (percent >= 75) { @@ -171,6 +181,7 @@ int16_t EnviroDIYPublisher::publishData(Client* outClient, bool forceFlush) { // that function said so we know to do it after we record this data point. // we also flush if requested (in which case the internet is connected too) bool willFlush = connectionNeeded() || forceFlush; + MS_DBG(F("Publishing record to buffer. Will flush:"), willFlush); // create record to hold timestamp and variable values in the log buffer int record = _logBuffer.addRecord(Logger::markedLocalEpochTime); @@ -199,8 +210,6 @@ int16_t EnviroDIYPublisher::flushDataBuffer(Client* outClient) { char tempBuffer[37] = ""; uint16_t did_respond = 0; - MS_DBG(F("Outgoing JSON size:"), calculateJsonSize()); - // Open a TCP/IP connection to the Enviro DIY Data Portal (WebSDL) MS_DBG(F("Connecting client")); MS_START_DEBUG_TIMER; From 88b9c1cb4fd573bae563b020c49b0cd02892afe3 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 21 Sep 2023 12:13:21 -0400 Subject: [PATCH 058/138] Non-static buffer Signed-off-by: Sara Damiano --- examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino | 2 -- src/publishers/EnviroDIYPublisher.cpp | 2 -- src/publishers/EnviroDIYPublisher.h | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino b/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino index d1c315e45..90742932d 100644 --- a/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino +++ b/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino @@ -317,8 +317,6 @@ void setup() { // Begin the logger dataLogger.begin(); - EnviroDIYPOST.begin(dataLogger, &modem.gsmClient, registrationToken, - samplingFeature); // Note: Please change these battery voltages to match your battery // Set up the sensors, except at lowest battery level diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index a4e4ce023..b362df6e9 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -11,8 +11,6 @@ #include "EnviroDIYPublisher.h" -LogBuffer EnviroDIYPublisher::_logBuffer; - // ============================================================================ // Functions for the EnviroDIY data portal receivers. // ============================================================================ diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index 6f4221e70..1f301a920 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -196,7 +196,7 @@ class EnviroDIYPublisher : public dataPublisher { static const char* timestampTag; ///< The JSON feature timestamp tag /**@}*/ - static LogBuffer _logBuffer; + LogBuffer _logBuffer; // actually transmit rather than just buffer data int16_t flushDataBuffer(Client* outClient); From c247aa6a82a0f08a8731c6e8ae90de30dcc51175 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 21 Sep 2023 12:13:32 -0400 Subject: [PATCH 059/138] steps toward fifo Signed-off-by: Sara Damiano --- src/LogBuffer.cpp | 9 +++++++-- src/LogBuffer.h | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/LogBuffer.cpp b/src/LogBuffer.cpp index b79b51edf..ca4eab926 100644 --- a/src/LogBuffer.cpp +++ b/src/LogBuffer.cpp @@ -24,12 +24,15 @@ void LogBuffer::setNumVariables(uint8_t numVariables_) { numVariables = numVariables_; // this scrambles all the data in the buffer so clear it out - numRecords = 0; + clear(); } void LogBuffer::clear(void) { // clear out the buffer - numRecords = 0; + numRecords = 0; + dataBufferTail = 0; + dataBufferHead = 0; + _bufferOverflow = false; } uint8_t LogBuffer::getNumVariables(void) { @@ -48,6 +51,7 @@ uint8_t LogBuffer::getPercentFull(void) { } int LogBuffer::addRecord(uint32_t timestamp) { + // check how many records currently exist int record = numRecords; // compute position of the new record's timestamp in the buffer // (the timestamp is the first data in the record) @@ -60,6 +64,7 @@ int LogBuffer::addRecord(uint32_t timestamp) { sizeof(uint32_t)); numRecords += 1; // just added another record + // return the index of the record number just created return record; } diff --git a/src/LogBuffer.h b/src/LogBuffer.h index b4b241a53..756ac3d8e 100644 --- a/src/LogBuffer.h +++ b/src/LogBuffer.h @@ -111,7 +111,7 @@ class LogBuffer { uint32_t getRecordTimestamp(int record); /** - * @brief Gets the value of a particular vaiable in a particular record. + * @brief Gets the value of a particular variable in a particular record. * * @param[in] record The record * @param[in] variable The variable @@ -126,6 +126,19 @@ class LogBuffer { */ uint8_t dataBuffer[MS_LOG_DATA_BUFFER_SIZE]; + /** + * @brief Index of buffer head. + */ + uint16_t dataBufferTail; + /** + * @brief Index of buffer tail. + */ + uint16_t dataBufferHead; + /** + * @brief The buffer overflow status + */ + bool _bufferOverflow = false; + /** * @brief Number of records currently in the buffer. */ From 446f0b9af5f2467e98c3e2a1585504b16640f0fe Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 20 May 2024 14:39:23 -0400 Subject: [PATCH 060/138] Made the EnviroDIY host/path/port settable Signed-off-by: Sara Damiano --- src/publishers/EnviroDIYPublisher.cpp | 54 ++++++++++++++++++++++++--- src/publishers/EnviroDIYPublisher.h | 48 ++++++++++++++++++++++-- 2 files changed, 93 insertions(+), 9 deletions(-) diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index b362df6e9..b734722bc 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -18,9 +18,6 @@ // Constant values for post requests // I want to refer to these more than once while ensuring there is only one copy // in memory -const char* EnviroDIYPublisher::postEndpoint = "/api/data-stream/"; -const char* EnviroDIYPublisher::enviroDIYHost = "data.envirodiy.org"; -const int EnviroDIYPublisher::enviroDIYPort = 80; const char* EnviroDIYPublisher::tokenHeader = "\r\nTOKEN: "; const char* EnviroDIYPublisher::contentLengthHeader = "\r\nContent-Length: "; const char* EnviroDIYPublisher::contentTypeHeader = @@ -31,15 +28,25 @@ const char* EnviroDIYPublisher::timestampTag = "\",\"timestamp\":["; // Constructors -EnviroDIYPublisher::EnviroDIYPublisher() : dataPublisher() {} +EnviroDIYPublisher::EnviroDIYPublisher() : dataPublisher() { + setHost("monitormywatershed.org"); + setPath("/api/data-stream/"); + setPort(80); +} EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, int sendEveryX) : dataPublisher(baseLogger, sendEveryX) { _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); + setHost("monitormywatershed.org"); + setPath("/api/data-stream/"); + setPort(80); } EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, Client* inClient, int sendEveryX) : dataPublisher(baseLogger, inClient, sendEveryX) { _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); + setHost("monitormywatershed.org"); + setPath("/api/data-stream/"); + setPort(80); } EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, const char* registrationToken, @@ -49,6 +56,9 @@ EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, setToken(registrationToken); _baseLogger->setSamplingFeatureUUID(samplingFeatureUUID); _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); + setHost("monitormywatershed.org"); + setPath("/api/data-stream/"); + setPort(80); } EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, Client* inClient, const char* registrationToken, @@ -58,11 +68,45 @@ EnviroDIYPublisher::EnviroDIYPublisher(Logger& baseLogger, Client* inClient, setToken(registrationToken); _baseLogger->setSamplingFeatureUUID(samplingFeatureUUID); _logBuffer.setNumVariables(_baseLogger->getArrayVarCount()); + setHost("monitormywatershed.org"); + setPath("/api/data-stream/"); + setPort(80); } // Destructor EnviroDIYPublisher::~EnviroDIYPublisher() {} +// Returns the data destination +String EnviroDIYPublisher::getHost(void) { + return String(enviroDIYHost); +} + +// Returns the data destination +void EnviroDIYPublisher::setHost(const char* host) { + enviroDIYHost = host; +} + +// Returns the data destination +String EnviroDIYPublisher::getPath(void) { + return String(enviroDIYPath); +} + +// Returns the data destination +void EnviroDIYPublisher::setPath(const char* endpoint) { + enviroDIYPath = endpoint; +} + +// Returns the data destination +int EnviroDIYPublisher::getPort(void) { + return enviroDIYPort; +} + +// Returns the data destination +void EnviroDIYPublisher::setPort(int port) { + enviroDIYPort = port; +} + + void EnviroDIYPublisher::setToken(const char* registrationToken) { _registrationToken = registrationToken; } @@ -217,7 +261,7 @@ int16_t EnviroDIYPublisher::flushDataBuffer(Client* outClient) { // copy the initial post header into the tx buffer txBufferAppend(postHeader); - txBufferAppend(postEndpoint); + txBufferAppend(enviroDIYPath); txBufferAppend(HTTPtag); // add the rest of the HTTP POST headers to the outgoing buffer diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index 1f301a920..12bd93ef9 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -107,9 +107,49 @@ class EnviroDIYPublisher : public dataPublisher { // Returns the data destination String getEndpoint(void) override { - return String(enviroDIYHost); + return String(enviroDIYHost) + String(enviroDIYPath); } + /** + * @brief Get the EnviroDIY/Monitor My Watershed web host + * + * @return *String* The EnviroDIY/Monitor My Watershed web host + */ + String getHost(void); + + /** + * @brief Set the EnviroDIY/Monitor My Watershed web host + * + * @param host The EnviroDIY/Monitor My Watershed web host + */ + void setHost(const char* host); + + /** + * @brief Get the EnviroDIY/Monitor My Watershed API path + * + * @return *String* The EnviroDIY/Monitor My Watershed API path + */ + String getPath(void); + /** + * @brief Set the EnviroDIY/Monitor My Watershed API path + * + * @param endpoint The EnviroDIY/Monitor My Watershed API path + */ + void setPath(const char* endpoint); + + /** + * @brief Get the EnviroDIY/Monitor My Watershed API port + * + * @return *int* The EnviroDIY/Monitor My Watershed API port + */ + int getPort(void); + /** + * @brief Set the EnviroDIY/Monitor My Watershed API port + * + * @param port The EnviroDIY/Monitor My Watershed API port + */ + void setPort(int port); + // Adds the site registration token /** * @brief Set the site registration token @@ -178,9 +218,9 @@ class EnviroDIYPublisher : public dataPublisher { * * @{ */ - static const char* postEndpoint; ///< The endpoint - static const char* enviroDIYHost; ///< The host name - static const int enviroDIYPort; ///< The host port + const char* enviroDIYPath; ///< The api path + const char* enviroDIYHost; ///< The host name + int enviroDIYPort; ///< The host port static const char* tokenHeader; ///< The token header text static const char* contentLengthHeader; ///< The content length header text static const char* contentTypeHeader; ///< The content type header text From f3c9d2501fd196c14947ce7f21b6e3d1009dd08c Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 20 May 2024 14:45:39 -0400 Subject: [PATCH 061/138] CR Signed-off-by: Sara Damiano --- src/publishers/EnviroDIYPublisher.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/publishers/EnviroDIYPublisher.cpp b/src/publishers/EnviroDIYPublisher.cpp index b734722bc..ba3a06465 100644 --- a/src/publishers/EnviroDIYPublisher.cpp +++ b/src/publishers/EnviroDIYPublisher.cpp @@ -11,6 +11,7 @@ #include "EnviroDIYPublisher.h" + // ============================================================================ // Functions for the EnviroDIY data portal receivers. // ============================================================================ From c81f7146274fffdd7bb51724b919a854dcde27b7 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 20 May 2024 15:30:40 -0400 Subject: [PATCH 062/138] Re-add testing mode Signed-off-by: Sara Damiano --- ChangeLog.md | 3 +++ src/LoggerBase.cpp | 14 ++++++++++++-- src/LoggerBase.h | 20 +++++++++++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 54f53cbc7..408f98e59 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed ### Added +- Added support for caching readings in RAM and sending in batches. +This currently only works on the EnviroDIY/Monitor My Watershed Publisher. +Thank you to [Thomas Watson](https://github.com/tpwrules) for this work. ### Removed diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 0a04685c9..72c5b4029 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -32,6 +32,7 @@ uint32_t Logger::markedLocalEpochTime = 0; uint32_t Logger::markedUTCEpochTime = 0; // Initialize the testing/logging flags volatile bool Logger::isLoggingNow = false; +volatile bool Logger::isTestingNow = false; volatile bool Logger::startTesting = false; // Initialize the RTC for the SAMD boards using build in RTC @@ -52,6 +53,7 @@ Logger::Logger(const char* loggerID, uint16_t loggingIntervalMinutes, // Set the testing/logging flags to false isLoggingNow = false; + isTestingNow = false; startTesting = false; // Set the initial pin values @@ -72,6 +74,7 @@ Logger::Logger(const char* loggerID, uint16_t loggingIntervalMinutes, // Set the testing/logging flags to false isLoggingNow = false; + isTestingNow = false; startTesting = false; // Clear arrays @@ -82,6 +85,7 @@ Logger::Logger(const char* loggerID, uint16_t loggingIntervalMinutes, Logger::Logger() { // Set the testing/logging flags to false isLoggingNow = false; + isTestingNow = false; startTesting = false; // Clear arrays @@ -1252,7 +1256,7 @@ bool Logger::logToSD(void) { // A static function if you'd prefer to enter testing based on an interrupt void Logger::testingISR() { MS_DEEP_DBG(F("Testing interrupt!")); - if (!Logger::isLoggingNow) { + if (!Logger::isTestingNow && !Logger::isLoggingNow) { Logger::startTesting = true; MS_DEEP_DBG(F("Testing flag has been set.")); } @@ -1488,6 +1492,9 @@ void Logger::logData(bool sleepBeforeReturning) { Logger::startTesting = false; } + // Check if it was instead the testing interrupt that woke us up + if (Logger::startTesting) testingMode(); + if (sleepBeforeReturning) { // Sleep systemSleep(); @@ -1607,8 +1614,11 @@ void Logger::logDataAndPublish(bool sleepBeforeReturning) { Logger::startTesting = false; } + // Check if it was instead the testing interrupt that woke us up + if (Logger::startTesting) testingMode(); + if (sleepBeforeReturning) { - // Sleep + // Call the processor sleep systemSleep(); } } diff --git a/src/LoggerBase.h b/src/LoggerBase.h index 992b0fbd6..ed7e2e53e 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -400,7 +400,7 @@ class Logger { * @brief The initial number of samples to log at an interval of 1 minute * for fast field verification */ - uint8_t _initialShortIntervals = 5; + uint8_t _initialShortIntervals = 0; /** * @brief Digital pin number on the mcu controlling the SD card slave * select. @@ -1129,6 +1129,19 @@ class Logger { * on the pin assigned for "testing" mode. */ static void testingISR(void); + + /** + * @brief Execute testing mode. + * + * In testing mode, the logger uses the loggerModem, if attached, to connect + * to the internet. It then powers up all sensors tied to variable in the + * internal variable array. The logger then updates readings from all + * sensors 25 times with a 5 second wait in between. All results are output + * to the "main" output - ie Serial - and NOT to the SD card. After 25 + * measurements, the sensors are put to sleep, the modem is disconnected + * from the internet, and the logger goes back to sleep. + */ + virtual void testingMode(); /**@}*/ // ===================================================================== // @@ -1212,6 +1225,11 @@ class Logger { * sensors or writing to the SD card */ static volatile bool isLoggingNow; + /** + * @brief Internal flag set to true when the logger is going through the + * "testing mode" routine. + */ + static volatile bool isTestingNow; /** * @brief Internal flag set to true with then logger should begin the * "testing mode" routine when it finishes other operations. From 06a7a86f120d4a6b7e772a1abd0e137a099c10cb Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 20 May 2024 16:01:49 -0400 Subject: [PATCH 063/138] Delete un-finished Dwyer Signed-off-by: Sara Damiano --- src/sensors/DwyerSBLT2.cpp | 117 ------------ src/sensors/DwyerSBLT2.h | 361 ------------------------------------- 2 files changed, 478 deletions(-) delete mode 100644 src/sensors/DwyerSBLT2.cpp delete mode 100644 src/sensors/DwyerSBLT2.h diff --git a/src/sensors/DwyerSBLT2.cpp b/src/sensors/DwyerSBLT2.cpp deleted file mode 100644 index 3a66e7203..000000000 --- a/src/sensors/DwyerSBLT2.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/** - * @file CampbellOBS3.cpp - * @copyright 2017-2022 Stroud Water Research Center - * Part of the EnviroDIY ModularSensors library for Arduino - * @author Sara Geleskie Damiano - * - * @brief Implements the CampbellOBS3 class. - */ - - -#include "DwyerSBLT2.h" -#include - - -// The constructor - need the power pin, the data pin, and the calibration info -DwyerSBLT2::DwyerSBLT2(int8_t powerPin, uint8_t adsChannel, - float conversion_coefficient, float conversion_constant, - uint8_t i2cAddress, uint8_t measurementsToAverage) - : Sensor("DwyerSBLT2", SBLT2_NUM_VARIABLES, SBLT2_WARM_UP_TIME_MS, - SBLT2_STABILIZATION_TIME_MS, SBLT2_MEASUREMENT_TIME_MS, powerPin, - -1, measurementsToAverage, SBLT2_INC_CALC_VARIABLES), - _adsChannel(adsChannel), - _conversion_coefficient(conversion_coefficient), - _conversion_constant(conversion_constant), - _i2cAddress(i2cAddress) {} -// Destructor -DwyerSBLT2::~DwyerSBLT2() {} - - -String DwyerSBLT2::getSensorLocation(void) { -#ifndef MS_USE_ADS1015 - String sensorLocation = F("ADS1115_0x"); -#else - String sensorLocation = F("ADS1015_0x"); -#endif - sensorLocation += String(_i2cAddress, HEX); - sensorLocation += F("_Channel"); - sensorLocation += String(_adsChannel); - return sensorLocation; -} - -bool DwyerSBLT2::addSingleMeasurementResult(void) { - // Variables to store the results in - float adcVoltage = -9999; - float calibResult = -9999; - - // Check a measurement was *successfully* started (status bit 6 set) - // Only go on to get a result if it was - if (bitRead(_sensorStatus, 6)) { - MS_DBG(getSensorNameAndLocation(), F("is reporting:")); - -// Create an Auxillary ADD object -// We create and set up the ADC object here so that each sensor using -// the ADC may set the gain appropriately without effecting others. -#ifndef MS_USE_ADS1015 - Adafruit_ADS1115 ads(_i2cAddress); // Use this for the 16-bit version -#else - Adafruit_ADS1015 ads(_i2cAddress); // Use this for the 12-bit version -#endif - // ADS Library default settings: - // - TI1115 (16 bit) - // - single-shot mode (powers down between conversions) - // - 128 samples per second (8ms conversion time) - // - 2/3 gain +/- 6.144V range (limited to VDD +0.3V max) - // - TI1015 (12 bit) - // - single-shot mode (powers down between conversions) - // - 1600 samples per second (625µs conversion time) - // - 2/3 gain +/- 6.144V range (limited to VDD +0.3V max) - - // Bump the gain up to 1x = +/- 4.096V range - // Sensor return range is 0-2.5V, but the next gain option is 2x which - // only allows up to 2.048V - ads.setGain(GAIN_ONE); - // Begin ADC - ads.begin(); - - // Print out the calibration curve - MS_DBG(F(" Input calibration Curve:"), _conversion_coefficient, - F("x +"), _conversion_constant); - - // Read Analog to Digital Converter (ADC) - // Taking this reading includes the 8ms conversion delay. - // We're allowing the ADS1115 library to do the bit-to-volts conversion - // for us - adcVoltage = - ads.readADC_SingleEnded_V(_adsChannel); // Getting the reading - MS_DBG(F(" ads.readADC_SingleEnded_V("), _adsChannel, F("):"), - adcVoltage); - - if (adcVoltage < 5.0 && adcVoltage > -0.3) { - // Skip results out of range - // Apply the unique calibration curve for the given sensor - calibResult = ((_conversion_coefficient * adcVoltage) - - _conversion_constant) / - 1000; - MS_DBG(F(" calibResult:"), calibResult); - } else { // set invalid voltages back to -9999 - adcVoltage = -9999; - } - } else { - MS_DBG(getSensorNameAndLocation(), F("is not currently measuring!")); - } - - verifyAndAddMeasurementResult(SBLT2_DEPTH_VAR_NUM, calibResult); - verifyAndAddMeasurementResult(SBLT2_VOLTAGE_VAR_NUM, adcVoltage); - - // Unset the time stamp for the beginning of this measurement - _millisMeasurementRequested = 0; - // Unset the status bits for a measurement request (bits 5 & 6) - _sensorStatus &= 0b10011111; - - if (adcVoltage < 5 && adcVoltage > -0.3) { - return true; - } else { - return false; - } -} diff --git a/src/sensors/DwyerSBLT2.h b/src/sensors/DwyerSBLT2.h deleted file mode 100644 index be8a61e0f..000000000 --- a/src/sensors/DwyerSBLT2.h +++ /dev/null @@ -1,361 +0,0 @@ -/** - * @file DwyerSBLT2.h - * @copyright 2017-2022 Stroud Water Research Center - * Part of the EnviroDIY ModularSensors library for Arduino - * @author Sara Geleskie Damiano - * - * @brief Contains the CampbellOBS3 sensor subclass and the variable subclasses - * CampbellOBS3_Turbidity and CampbellOBS3_Voltage. - * - * These are used for the Campbell Scientific OBS-3+. - * - * This depends on the soligen2010 fork of the Adafruit ADS1015 library. - */ -/* clang-format off */ -/** - * @defgroup sensor_obs3 Campbell OBS3+ - * Classes for the Campbell OBS3+ analog turbidity sensor. - * - * @ingroup analog_group - * - * @tableofcontents - * @m_footernavigation - * - * @section sensor_obs3_intro Introduction - * - * @warning This sensor is no longer manufactured. - * - * The OBS-3+ puts out a simple analog signal between 0 and 2.5V. When the - * sensor is purchased, included in the packaging is a calibration certificate - * to use to convert the voltage into turbidity. - * - * @note The 5V and 4-20mA versions of the OBS3+ are _not_ supported by this - * library. - * - * The OBS3+ supports two different turbidity ranges. The low and high range - * signals are read independently of each other - the signals are on different - * wires. Each range has a separate calibrations. - * - * Before applying any turbidity calibration, the analog output from the OBS3+ - * must be converted into a high resolution digital signal. See the - * [ADS1115 page](@ref analog_group) for details on the conversion. - * - * @section sensor_obs3_datasheet Sensor Datasheet - * - [Basic Concepts](https://github.com/EnviroDIY/ModularSensors/wiki/Sensor-Datasheets/Campbell-OBS3-Basics.pdf) - * - [Manual](https://github.com/EnviroDIY/ModularSensors/wiki/Sensor-Datasheets/Campbell-OBS3-Manual.pdf) - * - * @note Low and high range are treated as completely independent, so only 2 - * "variables" are measured by each sensor - one for the raw voltage and another - * for the calibrated turbidity. To get both high and low range values, create - * two sensor objects! - * - * @section sensor_obs3_flags Build flags - * - ```-D MS_USE_ADS1015``` - * - switches from the 16-bit ADS1115 to the 12 bit ADS1015 - * - * @section sensor_obs3_ctor Sensor Constructor - * {{ @ref CampbellOBS3::CampbellOBS3 }} - * - * ___ - * @section sensor_obs3_examples Example Code - * The Campbell OBS3+ is used in the @menulink{campbell_obs3} example. - * - * @menusnip{campbell_obs3} - */ -/* clang-format on */ - -// Header Guards -#ifndef SRC_SENSORS_DWYERSBLT2_H_ -#define SRC_SENSORS_DWYERSBLT2_H_ - -// Debugging Statement -// #define MS_CAMPBELLOBS3_DEBUG - -#ifdef MS_DWYERSBLT2_DEBUG -#define MS_DEBUGGING_STD "DWYERSBLT2" -#endif - -// Included Dependencies -#include "ModSensorDebugger.h" -#undef MS_DEBUGGING_STD -#include "VariableBase.h" -#include "SensorBase.h" - -// Sensor Specific Defines -/** @ingroup sensor_obs3 */ -/**@{*/ -/** - * @brief Sensor::_numReturnedValues; the SBLT2 will return raw voltage which - * will be converted into depth(m). - */ -#define SBLT2_NUM_VARIABLES 2 -/// @brief Sensor::_incCalcValues; depth is calculated from raw voltage -/// using the input calibration equation. -#define SBLT2_INC_CALC_VARIABLES 1 - -/** - * @anchor sensor_obs3_timing - * @name Sensor Timing - * The sensor timing for an OBS3+ - */ -/**@{*/ -/// @brief Sensor::_warmUpTime_ms; the ADS1115 warms up in 2ms. -#define SBLT2_WARM_UP_TIME_MS 2 -/// @brief Sensor::_stabilizationTime_ms; minimum stabilization time for the -/// OBS3 is 2s (2000ms). -#define SBLT2_STABILIZATION_TIME_MS 2000 -/// @brief Sensor::_measurementTime_ms; OBS3 takes 100ms to complete a -/// measurement - Maximum data rate = 10Hz (100ms/sample). -///#FIXME look to update to 50ms which is SLTB2 reported response time -#define SBLT2_MEASUREMENT_TIME_MS 100 -/**@}*/ - -/** - * @anchor sensor_obs3_turbidity - * @name Turbidity - * The turbidity variable from an OBS3+ - * - Range: (depends on sediment size, particle shape, and reflectivity) - * - Turbidity (low/high): - * - T1: 250/1000 NTU - * - T2: 500/2000 NTU - * - T3: 1000/4000 NTU - * - Mud: 5000 to 10,000 mg L–1 - * - Sand: 50,000 to 100,000 mg L–1 - * - Accuracy: (whichever is larger) - * - Turbidity: 2% of reading or 0.5 NTU - * - Mud: 2% of reading or 1 mg L–1 - * - Sand: 4% of reading or 10 mg L–1 - * - Resolution: - * - 16-bit ADC, Turbidity: - * - T1: 0.03125/0.125 NTU - * - T2: 0.0625/0.25 NTU - * - T3: 0.125/0.5 NTU - * - @m_span{m-dim}@ref #OBS3_RESOLUTION = 5@m_endspan - * - 12-bit ADC, Turbidity: - * - T1: 0.5/2.0 NTU - * - T2: 1.0/4.0 NTU - * - T3: 2.0/8.0 NTU - * - @m_span{m-dim}@ref #OBS3_RESOLUTION = 1@m_endspan - * - * {{ @ref CampbellOBS3_Turbidity::CampbellOBS3_Turbidity }} - */ -/**@{*/ -/// Variable number; depth is stored in sensorValues[0]. -#define SBLT2_DEPTH_VAR_NUM 0 -#ifdef MS_USE_ADS1015 -/// @brief Decimals places in string representation; depth should have 1. -#define SBLT2_RESOLUTION 1 -#else -/// @brief Decimals places in string representation; depth should have 5. -#define SBLT2_RESOLUTION 5 -#endif -/// @brief Variable name in -/// [ODM2 controlled vocabulary](http://vocabulary.odm2.org/variablename/); -/// "turbidity" -#define SBLT2_DEPTH_VAR_NAME "Depth" -/// @brief Variable unit name in -/// [ODM2 controlled vocabulary](http://vocabulary.odm2.org/units/); -/// "nephelometricTurbidityUnit" (NTU) -#define SBLT2_DEPTH_UNIT_NAME "Meter" -/// @brief Default variable short code; "OBS3Turbidity" -#define SBLT2_DEPTH_DEFAULT_CODE "SBLT2Depth" -/**@}*/ - -/** - * @anchor sensor_obs3_voltage - * @name Voltage - * The voltage variable from an OBS3+ - * - Range is 0 to 2.5V - * - Accuracy: - * - 16-bit ADC (ADS1115): < 0.25% (gain error), < 0.25 LSB (offset errror) - * - @m_span{m-dim}@ref #OBS3_VOLTAGE_RESOLUTION = 4@m_endspan - * - 12-bit ADC (ADS1015, using build flag ```MS_USE_ADS1015```): < 0.15% - * (gain error), < 3 LSB (offset errror) - * - @m_span{m-dim}@ref #OBS3_VOLTAGE_RESOLUTION = 1@m_endspan - * - * {{ @ref CampbellOBS3_Voltage::CampbellOBS3_Voltage }} - */ -/**@{*/ -/// Variable number; voltage is stored in sensorValues[1]. -#define SBLT2_VOLTAGE_VAR_NUM 1 -/// @brief Variable name in -/// [ODM2 controlled vocabulary](http://vocabulary.odm2.org/variablename/); -/// "voltage" -#define SBLT2_VOLTAGE_VAR_NAME "voltage" -/// @brief Variable unit name in -/// [ODM2 controlled vocabulary](http://vocabulary.odm2.org/units/); "volt" -#define SBLT2_VOLTAGE_UNIT_NAME "volt" -/// @brief Default variable short code; "OBS3Voltage" -#define SBLT2_VOLTAGE_DEFAULT_CODE "SBLT2Voltage" - -#ifdef MS_USE_ADS1015 -/// @brief Decimals places in string representation; voltage should have 1. -/// - Resolution: -/// - 16-bit ADC (ADS1115): 0.125 mV -#define SBLT2_VOLTAGE_RESOLUTION 1 -#else -/// @brief Decimals places in string representation; voltage should have 4. -/// - Resolution: -/// - 12-bit ADC (ADS1015, using build flag ```MS_USE_ADS1015```): 2 mV -#define SBLT2_VOLTAGE_RESOLUTION 4 -#endif -/**@}*/ - -/// @brief The assumed address of the ADS1115, 1001 000 (ADDR = GND) -#define ADS1115_ADDRESS 0x48 - -/* clang-format off */ -/** - * @brief The Sensor sub-class for the - * [Campbell OBS3 analog turbidity sensor](@ref sensor_obs3). - * - * Low and high range are treated as completely independent, so only 2 - * "variables" are measured by each sensor - one for the raw voltage and another - * for the calibrated turbidity. To get both high and low range values, create - * two sensor objects! - * - * @ingroup sensor_obs3 - */ -/* clang-format on */ -class DwyerSBLT2 : public Sensor { - public: - // The constructor - need the power pin, the ADS1X15 data channel, and the - // calibration info - /** - * @brief Construct a new Campbell OBS3 object - need the power pin, the - * ADS1X15 data channel, and the calibration info. - * - * @note ModularSensors only supports connecting the ADS1x15 to the primary - * hardware I2C instance defined in the Arduino core. Connecting the ADS to - * a secondary hardware or software I2C instance is *not* supported! - * - * @param powerPin The pin on the mcu controlling power to the OBS3+ - * Use -1 if it is continuously powered. - * - The ADS1x15 requires an input voltage of 2.0-5.5V, but this library - * assumes the ADS is powered with 3.3V. - * - The OBS-3 itself requires a 5-15V power supply, which can be turned off - * between measurements. - * @param adsChannel The analog data channel _on the TI ADS1115_ that the - * OBS3 is connected to (0-3). - * @param x2_coeff_A The x2 (A) coefficient for the calibration _in volts_ - * @param x1_coeff_B The x (B) coefficient for the calibration _in volts_ - * @param x0_coeff_C The x0 (C) coefficient for the calibration _in volts_ - * @param i2cAddress The I2C address of the ADS 1x15, default is 0x48 (ADDR - * = GND) - * @param measurementsToAverage The number of measurements to take and - * average before giving a "final" result from the sensor; optional with a - * default value of 1. - */ - DwyerSBLT2(int8_t powerPin, uint8_t adsChannel, - float conversion_coefficient, float conversion_constant, - uint8_t i2cAddress = ADS1115_ADDRESS, - uint8_t measurementsToAverage = 1); - /** - * @brief Destroy the Dwyer SBLT2 object - */ - ~DwyerSBLT2(); - - /** - * @copydoc Sensor::getSensorLocation() - */ - String getSensorLocation(void) override; - - /** - * @copydoc Sensor::addSingleMeasurementResult() - */ - bool addSingleMeasurementResult(void) override; - - private: - uint8_t _adsChannel; - float _conversion_constant, _conversion_coefficient; - uint8_t _i2cAddress; -}; - - -// The main variable returned is turbidity -// To utilize both high and low gain turbidity, you must create *two* sensor -// objects on two different data channels and then create two variable objects, -// one tied to each sensor. -/* clang-format off */ -/** - * @brief The Variable sub-class used for the - * [turbidity output](@ref sensor_obs3_turbidity) from a [Campbell OBS3+](@ref sensor_obs3). - * - * @ingroup sensor_obs3 - */ -/* clang-format on */ -class DwyerSBLT2_Depth : public Variable { - public: - /** - * @brief Construct a new CampbellOBS3_Turbidity object. - * - * @param parentSense The parent CampbellOBS3 providing the result - * values. - * @param uuid A universally unique identifier (UUID or GUID) for the - * variable; optional with the default value of an empty string. - * @param varCode A short code to help identify the variable in files; - * optional with a default value of "OBS3Turbidity". - */ - explicit DwyerSBLT2_Depth(DwyerSBLT2* parentSense, const char* uuid = "", - const char* varCode = SBLT2_DEPTH_DEFAULT_CODE) - : Variable(parentSense, (const uint8_t)SBLT2_DEPTH_VAR_NUM, - (uint8_t)SBLT2_RESOLUTION, SBLT2_DEPTH_VAR_NAME, - SBLT2_DEPTH_UNIT_NAME, varCode, uuid) {} - /** - * @brief Construct a new CampbellOBS3_Turbidity object. - * - * @note This must be tied with a parent CampbellOBS3 before it can be used. - */ - DwyerSBLT2_Depth() - : Variable((const uint8_t)SBLT2_DEPTH_VAR_NUM, - (uint8_t)SBLT2_RESOLUTION, SBLT2_DEPTH_VAR_NAME, - SBLT2_DEPTH_UNIT_NAME, SBLT2_DEPTH_DEFAULT_CODE) {} - ~DwyerSBLT2_Depth() {} -}; - - -// Also returning raw voltage -/* clang-format off */ -/** - * @brief The Variable sub-class used for the - * [raw voltage output](@ref sensor_obs3_voltage) from a [Campbell OBS3+](@ref sensor_obs3). - * - * This could be helpful if the calibration equation was typed incorrectly. - * - * @ingroup sensor_obs3 - */ -/* clang-format on */ -class DwyerSBLT2_Voltage : public Variable { - public: - /** - * @brief Construct a new CampbellOBS3_Voltage object. - * - * @param parentSense The parent CampbellOBS3 providing the result - * values. - * @param uuid A universally unique identifier (UUID or GUID) for the - * variable; optional with the default value of an empty string. - * @param varCode A short code to help identify the variable in files; - * optional with a default value of "OBS3Voltage". - */ - explicit DwyerSBLT2_Voltage( - DwyerSBLT2* parentSense, const char* uuid = "", - const char* varCode = SBLT2_VOLTAGE_DEFAULT_CODE) - : Variable(parentSense, (const uint8_t)SBLT2_VOLTAGE_VAR_NUM, - (uint8_t)SBLT2_VOLTAGE_RESOLUTION, SBLT2_VOLTAGE_VAR_NAME, - SBLT2_VOLTAGE_UNIT_NAME, varCode, uuid) {} - /** - * @brief Construct a new CampbellOBS3_Voltage object. - * - * @note This must be tied with a parent CampbellOBS3 before it can be used. - */ - DwyerSBLT2_Voltage() - : Variable((const uint8_t)SBLT2_VOLTAGE_VAR_NUM, - (uint8_t)SBLT2_VOLTAGE_RESOLUTION, SBLT2_VOLTAGE_VAR_NAME, - SBLT2_VOLTAGE_UNIT_NAME, SBLT2_VOLTAGE_DEFAULT_CODE) {} - /** - * @brief Destroy the CampbellOBS3_Voltage object - no action needed. - */ - ~DwyerSBLT2_Voltage() {} -}; -/**@}*/ -#endif // SRC_SENSORS_CAMPBELLOBS3_H_ From feac5b5dba942a3b649fbaa354d327cc7ac002b4 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 23 May 2024 16:45:34 -0400 Subject: [PATCH 064/138] Reorder maxbotix ctor, and default max range Signed-off-by: Sara Damiano --- examples/menu_a_la_carte/menu_a_la_carte.ino | 10 ++++++--- src/sensors/MaxBotixSonar.cpp | 23 +++++++++++--------- src/sensors/MaxBotixSonar.h | 12 +++++----- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/examples/menu_a_la_carte/menu_a_la_carte.ino b/examples/menu_a_la_carte/menu_a_la_carte.ino index 89ceb7e85..de2ee9675 100644 --- a/examples/menu_a_la_carte/menu_a_la_carte.ino +++ b/examples/menu_a_la_carte/menu_a_la_carte.ino @@ -1610,10 +1610,11 @@ Variable* nanolevHeight = new KellerNanolevel_Height( const int8_t SonarPower = sensorPowerPin; // Excite (power) pin const int8_t Sonar1Trigger = -1; // Trigger pin // Trigger should be a *unique* negative number if unconnected -const uint8_t sonar1NumberReadings = 3; // The number of readings to average +const int16_t Sonar1MaxRange = 9999; // Maximum range of sonar +const uint8_t sonar1NumberReadings = 3; // The number of readings to average // Create a MaxBotix Sonar sensor object -MaxBotixSonar sonar1(sonarSerial, SonarPower, Sonar1Trigger, +MaxBotixSonar sonar1(sonarSerial, SonarPower, Sonar1Trigger, Sonar1MaxRange, sonar1NumberReadings); // Create an ultrasonic range variable pointer @@ -2980,7 +2981,10 @@ void greenredflash(uint8_t numFlash = 4, uint8_t rate = 75) { // Uses the processor sensor object to read the battery voltage // NOTE: This will actually return the battery level from the previous update! float getBatteryVoltage() { - if (mcuBoard.sensorValues[PROCESSOR_BATTERY_VAR_NUM] == -9999) mcuBoard.update(); + if (mcuBoard.sensorValues[PROCESSOR_BATTERY_VAR_NUM] == -9999 || + mcuBoard.sensorValues[PROCESSOR_BATTERY_VAR_NUM] == 0) { + mcuBoard.update(); + } return mcuBoard.sensorValues[PROCESSOR_BATTERY_VAR_NUM]; } /** End [working_functions] */ diff --git a/src/sensors/MaxBotixSonar.cpp b/src/sensors/MaxBotixSonar.cpp index 958f34aac..477654714 100644 --- a/src/sensors/MaxBotixSonar.cpp +++ b/src/sensors/MaxBotixSonar.cpp @@ -11,8 +11,9 @@ #include "MaxBotixSonar.h" -MaxBotixSonar::MaxBotixSonar(Stream* stream, int8_t powerPin, int16_t maxRange, int8_t triggerPin, - uint8_t measurementsToAverage, bool convertCm) +MaxBotixSonar::MaxBotixSonar(Stream* stream, int8_t powerPin, int8_t triggerPin, + int16_t maxRange, uint8_t measurementsToAverage, + bool convertCm) : Sensor("MaxBotixMaxSonar", HRXL_NUM_VARIABLES, HRXL_WARM_UP_TIME_MS, HRXL_STABILIZATION_TIME_MS, HRXL_MEASUREMENT_TIME_MS, powerPin, -1, measurementsToAverage), @@ -22,8 +23,9 @@ MaxBotixSonar::MaxBotixSonar(Stream* stream, int8_t powerPin, int16_t maxRange, _stream(stream) {} -MaxBotixSonar::MaxBotixSonar(Stream& stream, int8_t powerPin, int16_t maxRange, int8_t triggerPin, - uint8_t measurementsToAverage, bool convertCm) +MaxBotixSonar::MaxBotixSonar(Stream& stream, int8_t powerPin, int8_t triggerPin, + int16_t maxRange, uint8_t measurementsToAverage, + bool convertCm) : Sensor("MaxBotixMaxSonar", HRXL_NUM_VARIABLES, HRXL_WARM_UP_TIME_MS, HRXL_STABILIZATION_TIME_MS, HRXL_MEASUREMENT_TIME_MS, powerPin, -1, measurementsToAverage, HRXL_INC_CALC_VARIABLES), @@ -70,8 +72,12 @@ bool MaxBotixSonar::wake(void) { // ~160ms. Although we are waiting for them to complete in the // "waitForWarmUp" function, the values will still be in the serial buffer // and need to be read to be cleared out For an HRXL without temperature - // compensation, the headers are: HRXL-MaxSonar-WRL PN:MB7386 Copyright - // 2011-2013 MaxBotix Inc. RoHS 1.8b090 0713 TempI + // compensation, the headers are: + // HRXL-MaxSonar-WRL + // PN:MB7386 + // Copyright 2011-2013 MaxBotix Inc. + // RoHS 1.8b090 + // 0713 TempI // NOTE ALSO: Depending on what type of serial stream you are using, there // may also be a bunch of junk in the buffer that this will clear out. @@ -149,7 +155,6 @@ bool MaxBotixSonar::addSingleMeasurementResult(void) { _stream->read(); // To throw away the carriage return MS_DBG(F(" Sonar Range:"), result); rangeAttempts++; - // If it cannot obtain a result, the sonar is supposed to send a // value just above its max range. If the result becomes garbled or @@ -163,9 +168,7 @@ bool MaxBotixSonar::addSingleMeasurementResult(void) { } else { MS_DBG(F(" Good result found")); // convert result from cm to mm if convertCm is set to true - if (_convertCm == true) { - result *= 10; - } + if (_convertCm == true) { result *= 10; } success = true; } } diff --git a/src/sensors/MaxBotixSonar.h b/src/sensors/MaxBotixSonar.h index 0bb17c6a7..45f7d3f63 100644 --- a/src/sensors/MaxBotixSonar.h +++ b/src/sensors/MaxBotixSonar.h @@ -184,25 +184,25 @@ class MaxBotixSonar : public Sensor { * can be used. * @param powerPin The pin on the mcu controlling power to the MaxSonar. * Use -1 if it is continuously powered. - * @param maxRange Maximum valid measurement reported by the specific sensor - * model (e.g. 5000 or 9999 or 765). * - The MaxSonar requires a 2.7V - 5.5V power supply. * @param triggerPin The pin on the mcu controlling the "trigger" for the * MaxSonar. Use -1 or omit for continuous ranging. + * @param maxRange Maximum valid measurement reported by the specific sensor + * model (e.g. 5000 or 9999 or 765). * @param measurementsToAverage The number of measurements to take and * average before giving a "final" result from the sensor; optional with a * default value of 1. * @param convertCm Convert centimeter range data from certain models to * millimeters. Default false. */ - MaxBotixSonar(Stream* stream, int8_t powerPin, int16_t maxRange, - int8_t triggerPin = -1, uint8_t measurementsToAverage = 1, + MaxBotixSonar(Stream* stream, int8_t powerPin, int8_t triggerPin = -1, + int16_t maxRange = 9999, uint8_t measurementsToAverage = 1, bool convertCm = false); /** * @copydoc MaxBotixSonar::MaxBotixSonar */ - MaxBotixSonar(Stream& stream, int8_t powerPin, int16_t maxRange, - int8_t triggerPin = -1, uint8_t measurementsToAverage = 1, + MaxBotixSonar(Stream& stream, int8_t powerPin, int8_t triggerPin = -1, + int16_t maxRange = 9999, uint8_t measurementsToAverage = 1, bool convertCm = false); /** * @brief Destroy the MaxBotix Sonar object From 0cae7cb82b95558aa3c3dcdb35135c2d24e17f24 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 23 May 2024 16:45:54 -0400 Subject: [PATCH 065/138] Ensure 7080's netlight is on Signed-off-by: Sara Damiano --- src/modems/SIMComSIM7080.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/modems/SIMComSIM7080.cpp b/src/modems/SIMComSIM7080.cpp index 29060d8fc..a85d712a1 100644 --- a/src/modems/SIMComSIM7080.cpp +++ b/src/modems/SIMComSIM7080.cpp @@ -44,6 +44,21 @@ bool SIMComSIM7080::extraModemSetup(void) { // problems by maxing out the send buffer size. This size should accommodate // a completely full 8K LogBuffer and a crappy connection. gsmModem.sendAT(F("+CACFG=\"SNDBUF\",29200")); + gsmModem.waitResponse(); + + // Enable the netlight indicator + gsmModem.sendAT(F("+CNETLIGHT=1")); + gsmModem.waitResponse(); + // Enable netlight indication of GPRS status + // Enable, the netlight will be forced to enter into 64ms on/300ms off + // blinking state in GPRS data transmission service.Otherwise, the netlight + // state is not restricted. + gsmModem.sendAT(F("+CNETLIGHT=1")); + gsmModem.waitResponse(); + + // Enable the battery check functionality + gsmModem.sendAT(F("+CBATCHK=1")); + gsmModem.waitResponse(); return success; } From f562907f420129931804c354537a237a0598f863 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 28 May 2024 14:53:37 -0400 Subject: [PATCH 066/138] Text change Signed-off-by: Sara Damiano --- .github/workflows/build_examples.yaml | 2 +- docs/DoxygenLayout.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_examples.yaml b/.github/workflows/build_examples.yaml index bfdc620ee..a53fd8c0d 100644 --- a/.github/workflows/build_examples.yaml +++ b/.github/workflows/build_examples.yaml @@ -78,7 +78,7 @@ jobs: echo "LIBRARY_INSTALL_ZIP=https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_HEAD_REF}.zip" >> $GITHUB_ENV echo "LIBRARY_INSTALL_GIT=https://github.com/${GITHUB_REPOSITORY}.git#${GITHUB_HEAD_REF}" >> $GITHUB_ENV - - name: Set environment variable for PR's from any branch in EnviroDIY/ModularSensors + - name: Set environment variable for PR's from any fork of ModularSensors if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.name != github.repository run: | echo "Pull Request from the fork ${{ github.event.pull_request.head.repo.full_name }} at ${{ github.event.pull_request.head.ref }}" diff --git a/docs/DoxygenLayout.xml b/docs/DoxygenLayout.xml index 05380cd27..9dc8a05a6 100644 --- a/docs/DoxygenLayout.xml +++ b/docs/DoxygenLayout.xml @@ -325,4 +325,4 @@ - \ No newline at end of file + From 302f0afcb4479acd4b980293dea46f92e838e218 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 28 May 2024 15:21:14 -0400 Subject: [PATCH 067/138] Decrease buffer size for Mega, fix warnings Signed-off-by: Sara Damiano --- src/LogBuffer.h | 4 ++++ src/publishers/DreamHostPublisher.cpp | 2 +- src/publishers/ThingSpeakPublisher.cpp | 2 +- src/publishers/UbidotsPublisher.cpp | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/LogBuffer.h b/src/LogBuffer.h index 756ac3d8e..9d3151256 100644 --- a/src/LogBuffer.h +++ b/src/LogBuffer.h @@ -26,8 +26,12 @@ * compiling. 8192 bytes is a safe value for the Mayfly 1.1 with six variables. */ #ifndef MS_LOG_DATA_BUFFER_SIZE +#ifdef ARDUINO_AVR_MEGA2560 +#define MS_LOG_DATA_BUFFER_SIZE 2048 +#else #define MS_LOG_DATA_BUFFER_SIZE 8192 #endif +#endif #include #include diff --git a/src/publishers/DreamHostPublisher.cpp b/src/publishers/DreamHostPublisher.cpp index d30b7cbab..9089028ac 100644 --- a/src/publishers/DreamHostPublisher.cpp +++ b/src/publishers/DreamHostPublisher.cpp @@ -65,7 +65,7 @@ void DreamHostPublisher::begin(Logger& baseLogger, const char* dhUrl) { // Post the data to dream host. // int16_t DreamHostPublisher::postDataDreamHost(void) -int16_t DreamHostPublisher::publishData(Client* outClient, bool forceFlush) { +int16_t DreamHostPublisher::publishData(Client* outClient, bool) { // Create a buffer for the portions of the request and response char tempBuffer[37] = ""; uint16_t did_respond = 0; diff --git a/src/publishers/ThingSpeakPublisher.cpp b/src/publishers/ThingSpeakPublisher.cpp index efdf997dc..3b070088a 100644 --- a/src/publishers/ThingSpeakPublisher.cpp +++ b/src/publishers/ThingSpeakPublisher.cpp @@ -102,7 +102,7 @@ void ThingSpeakPublisher::begin(Logger& baseLogger, // This sends the data to ThingSpeak // bool ThingSpeakPublisher::mqttThingSpeak(void) -int16_t ThingSpeakPublisher::publishData(Client* outClient, bool forceFlush) { +int16_t ThingSpeakPublisher::publishData(Client* outClient, bool ) { bool retVal = false; // Make sure we don't have too many fields diff --git a/src/publishers/UbidotsPublisher.cpp b/src/publishers/UbidotsPublisher.cpp index 702baafd7..33f2993f9 100644 --- a/src/publishers/UbidotsPublisher.cpp +++ b/src/publishers/UbidotsPublisher.cpp @@ -113,7 +113,7 @@ void UbidotsPublisher::begin(Logger& baseLogger, // over that connection. // The return is the http status code of the response. // int16_t EnviroDIYPublisher::postDataEnviroDIY(void) -int16_t UbidotsPublisher::publishData(Client* outClient, bool forceFlush) { +int16_t UbidotsPublisher::publishData(Client* outClient, bool) { // Create a buffer for the portions of the request and response char tempBuffer[37] = ""; uint16_t did_respond = 0; From 07715a8c8ce8d613bad6e72b0e509cdcdce484a8 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 10 Jun 2024 11:44:18 -0400 Subject: [PATCH 068/138] Apply markdown lint Signed-off-by: Sara Damiano --- .gitignore | 9 +- ChangeLog.md | 183 ++++++++++--- README.md | 32 +-- docs/FAQ/Arduino-Streams.md | 12 +- docs/FAQ/Code-Debugging.md | 2 +- docs/FAQ/Deceasing-Memory-Use.md | 2 +- docs/FAQ/Developer-Setup.md | 4 +- docs/FAQ/Power-Parasites.md | 2 +- docs/FAQ/Processor-Compatibility.md | 16 +- docs/General-Sensor-Notes.md | 2 +- docs/Getting-Started/Getting-Started.md | 14 +- docs/Getting-Started/Library-Dependencies.md | 2 +- docs/Getting-Started/Physical-Dependencies.md | 2 +- docs/Getting-Started/Terminology.md | 16 +- docs/Modem-Notes.md | 14 +- examples/DRWI_2G/ReadMe.md | 16 +- examples/DRWI_DigiLTE/ReadMe.md | 16 +- examples/DRWI_Mayfly1/ReadMe.md | 6 +- examples/DRWI_Mayfly1_WiFi/ReadMe.md | 6 +- examples/DRWI_NoCellular/ReadMe.md | 16 +- examples/DRWI_SIM7080LTE/ReadMe.md | 4 +- examples/ReadMe.md | 42 +-- examples/baro_rho_correction/ReadMe.md | 14 +- examples/data_saving/ReadMe.md | 14 +- examples/double_logger/ReadMe.md | 12 +- examples/logging_to_MMW/ReadMe.md | 14 +- examples/logging_to_ThingSpeak/ReadMe.md | 12 +- examples/menu_a_la_carte/ReadMe.md | 246 +++++++++--------- .../simple_logging_LearnEnviroDIY/ReadMe.md | 12 +- examples/single_sensor/ReadMe.md | 10 +- src/LoggerBase.h | 10 +- 31 files changed, 430 insertions(+), 332 deletions(-) diff --git a/.gitignore b/.gitignore index 9c278f49b..66e0eaf39 100644 --- a/.gitignore +++ b/.gitignore @@ -84,14 +84,14 @@ barometric_correction/ __pycache__/ runDoxygen.bat docs/examples/* -output_doxygen.log -output_doxygen_run.log -output_mcss_run.log -output_mcss.log docs/examples.dox_x platformio_extra_envs.ini src/sensors/table.md cache +output_doxygen.log +output_doxygen_run.log +output_mcss_run.log +output_mcss.log docs/output_copyFunctions.log docs/output_documentExamples.log docs/output_fixSectionsInXml.log @@ -112,3 +112,4 @@ docs/Doxyfile.bak continuous_integration/output_check_component_inclusion.log continuous_integration/platformio_ci_local.ini pioScripts/install_shared_deps.py +runDoxygen_archive.bat diff --git a/ChangeLog.md b/ChangeLog.md index 408f98e59..7d3c3fd4a 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,4 +1,5 @@ # ChangeLog + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) @@ -7,15 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 *** - ## [Unreleased] ### Changed ### Added + - Added support for caching readings in RAM and sending in batches. This currently only works on the EnviroDIY/Monitor My Watershed Publisher. Thank you to [Thomas Watson](https://github.com/tpwrules) for this work. +- Added keywords.txt for Arduino IDE ### Removed @@ -23,10 +25,10 @@ Thank you to [Thomas Watson](https://github.com/tpwrules) for this work. *** - ## [0.35.0] ### Changed + - **BREAKING** Refactored how the publisher transmit buffer works. This will require adjustment to custom data publishers. - Update GitHub actions - Remove date from copyright for easier tracking @@ -41,39 +43,47 @@ If you are not using the GroPoint sensors which require many variables, I recomm - Add further debug printouts to the processor stats ### Added + - Support [GroPoint Profile GPLP-8 Eight-Segment Soil Moisture and Temperature Profiling Probe](https://www.gropoint.com/products/soil-sensors/gropoint-profile) - Support [Vega Puls 21 Radar](https://www.vega.com/en-us/products/product-catalog/level/radar/vegapuls-21) - Functions to enable and disable modem metadata polling by bitmask ### Removed + - Removed the (unused) sendOffset parameter from dataPublisherBase. ### Fixed + - Minor bug fixes for XBee Wifi - Handle no SIM card response from SIM7080G (EnviroDIY LTE Bee) - Fixed Keller debugging output. - Fixed file reference for SDFat 2.2.3 ### Known Issues + - The modem hardware, firmware, and serial number is only implemented for the Digi XBee WiFi. ## [0.34.1] ### Changed + - Incorporated improvements to the XBee Wifi - from [neilh10](https://github.com/EnviroDIY/ModularSensors/commits?author=neilh10) - #347 -WiFi S6B stability - tears dwon TCP/IP before going to sleep, doesn't automatically poll for meta data ### Added + - Added the ability to enable or disable polling of modem attached variables. By default, all polling is off, but polling is enabled for a modem sensor when a sensor is created and attached to a modem. This functionailty is inspired from [neilh10](https://github.com/EnviroDIY/ModularSensors/commits?author=neilh10). ### Fixed + - Fixed GitHub actions for pull requests from forks. ## [0.34.0] ### Changed + - **BREAKING** - Removed support for light sleep on Espressif modules. **This changes the order of the constructor for the ESP32 and ESP8266!** - The light sleep mode is non-functional anyway, and confusion over the sleep request pin was putting the board in a position not to sleep at all. @@ -84,12 +94,14 @@ This functionailty is inspired from [neilh10](https://github.com/EnviroDIY/Modul - Specify python version 3.x for actions (used by PlatformIO) ### Added + - Support Campbell RainVUE10 SDI-12 Precipitation Sensor [#416](https://github.com/EnviroDIY/ModularSensors/issues/416) - Support YosemiTech Y700 Pressor Sensor ([#421](https://github.com/EnviroDIY/ModularSensors/issues/421)) ### Removed ### Fixed + - Fixed bug in YosemiTech Y4000 Sonde ([#420](https://github.com/EnviroDIY/ModularSensors/issues/420)) - Fixed non-concurrent data fetch for SDI-12 when *NOT* using debugging. - Fixed internet connection when in "testing mode" @@ -98,33 +110,36 @@ This functionailty is inspired from [neilh10](https://github.com/EnviroDIY/Modul *** - ## [0.33.4] ### Fixed + - Increased warm-up and measurement time for Campbell ClariVUE-10 to work with the latest version of the sensor. -*** +*** ## [0.33.3] ### Fixed + - Increased measurement time for Hydros21 to work with the latest version of the sensor. -*** +*** ## [0.33.2] ### Fixed + - Fixed script to install and zip libraries for a release -*** +*** ## [0.33.1] - 2022-04-11 ### Changed ### Added + - Added a typedef and header for the ESP32 - This is just another name to the ESP8266 class to help any who don't know they're identical for our purposes. - **Example:** Created a new DRWI wifi example for workshop. @@ -138,6 +153,7 @@ This functionailty is inspired from [neilh10](https://github.com/EnviroDIY/Modul ## [0.33.0] - 2022-04-01 ### Changed + - **Breaking:** Renamed the static `markedEpochTime` variable to `markedLocalEpochTime`. - This was sometimes used in "complex" loops. Code utilizing it will have to be changed. - This is part of the effort to clarify where localized and UTC time are being used. @@ -168,6 +184,7 @@ These are *not* breaking changes at this time; the old class names are still usa - **Documentation:** Migrated to latest version of Doxygen (1.9.3). ### Added + - **Sensor** Added support for the [YosemiTech Y551 COD Sensor](http://en.yosemitech.com/aspcms/product/2020-5-8/94.html), which makes a UV254 light absorption and translates it to estimates of Chemical Oxygen Demand (COD) (or Total Organic Carbon (TOC)) and Turbidity. - NOTE that this upgrade removes the earlier Y550 from the library, as it was never tested and is no longer available form YosemiTech. If anyone has a Y550 sensor, the Y551 commands should work. Let us know if they don't. - **Sensor** Added support for the [YosemiTech Y560 Ammonium Probe](http://en.yosemitech.com/aspcms/product/2020-4-23/61.html), which is a mini sonde for three Ion Selective Electrode (ISE) sensors (pH, NH4+, K+) that together are used to provide a corrected estimate of total ammonium nitrogen (NH4_N) in mg/L. @@ -180,6 +197,7 @@ These are *not* breaking changes at this time; the old class names are still usa ### Removed ### Fixed + - Fixed memory leak for AOSong AM2315 thanks to @neilh10 *** @@ -187,6 +205,7 @@ These are *not* breaking changes at this time; the old class names are still usa ## [0.32.2] - 2021-11-23 ### Changed + - Restructured SDI-12 slightly to break out the start measurement functionality into a new function. - Modified Decagon 5-TM and Meter Teros 11 to use the SDI-12 get results function rather than addSingleMeasurmentResult. This will allow both sensors to honor the 'non-concurrent' flag, if that is set. @@ -195,6 +214,7 @@ Previously, they would not have. This required some changes with m.css to properly ignore the doxyfile.xml the current version generates. ### Added + - **Board:** Adds 1.0 and 1.1 as valid version numbers for the Mayfly. Does not yet support any new features of those boards. - Add a new parameter (internal variable) to the sensor base class for the number of internally calculated variables. These are used for values that we would always calculate for a sensor and depend only on the raw results of that single sensor. @@ -211,11 +231,13 @@ For the SDI-12 sensors, I'm actually using this to make sure I'm getting the num Reinstate support for AOSong DHT ### Changed + - **Documentation:** Restructured the changelog - **Documentation:** Restyled and corrected documentation links for new and renamed DRWI examples - **Continuous Integration:** Updated changelog reader and automated releaser ### Added + - Restored support for AOSong DHT sensor. *** @@ -225,6 +247,7 @@ Reinstate support for AOSong DHT Fix build without AOSong DHT ### Fixed + - Fixed build matrix to remove DHT *** @@ -234,9 +257,11 @@ Fix build without AOSong DHT Remove support for AOSong DHT ### Added + - **Examples:** Added a new example for the DRWI site using the new EnviroDIY bee based on the SIMCOM SIM7080G ### Removed + - **Breaking:** Temporarily **_REMOVED_** support for AOSong DHT sensor. - Intend to restore this after updating to support newest Adafruit DHT library @@ -247,18 +272,22 @@ Remove support for AOSong DHT Remove support for SoftwareWire for Atlas sensors ### Changed + - Changed build flags and created a pre-commit hook for myself to update the menu build matrix ### Added + - **Sensor:** Added support for [Campbell ClariVUE10](https://www.campbellsci.com/clarivue10) turbidity sensor ### Removed + - **Breaking:** Removed support for SoftwareWire for Atlas sensors. - The only supported version of a bit-banged (software) version of I2C removed inheritance from the core Wire library. Without inheritance, the parseFloat functions used by the Atlas sensors will not work. As I think this feature was completely unused for the Atlas sensors and I see no reason to use it with sensors that have completely flexible addressing, I removed it. ### Fixed + - Fixed GitHub actions for pull requests *** @@ -268,6 +297,7 @@ As I think this feature was completely unused for the Atlas sensors and I see no Fix YosemiTech Y533 ORP sensor outputs ### Fixed + - Modified `YosemitechY533.h` and examples to work with updated ORP `getValues()` function in https://github.com/EnviroDIY/YosemitechModbus released with v0.2.5. *** @@ -277,9 +307,11 @@ Fix YosemiTech Y533 ORP sensor outputs Create a ModularSensors.h ### Changed + - Modified examples to use Hydros 21 ### Added + - Created a ModularSensors.h file to include. This makes it much easiler to install and use the library from the Arduino CLI. - Modified examples to include the ModularSensors.h file @@ -292,6 +324,7 @@ This makes it much easiler to install and use the library from the Arduino CLI. Duplicate and Rename Hydros 21 ### Added + - **Sensor:** Created a new module for the Meter Hydros 21. This is exactly identical to the Decagon CTD in everything but the name. The Decagon CTD module still exists and can be used. @@ -306,6 +339,7 @@ The addition was only made to stop complaints about typing in an older name. SDI-12 Timing Sensor Customization ### Changed + - Allow each SDI-12 sensor to set the necessary command delay for that sensor. - Per protocol, sensors are allowed to take up to 100ms after receiving a break before being ready to receive a command. This allows each sensor to specify what delay it needs. @@ -319,6 +353,7 @@ This was added to support conflicting delay needs; the RDO needed a short delay, Valid version number ### Fixed + - Use a valid semantic version number *** @@ -328,6 +363,7 @@ Valid version number Gigantic SDI-12 bug ### Fixed + - Fixes an **_EGREGIOUS_** error in the SDI-12 code causing the code to lock up if debugging was off (but always work with it on) - [Issue #346](https://github.com/EnviroDIY/ModularSensors/issues/346) - This was first introduced in [0.27.5](https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.27.5) @@ -340,9 +376,11 @@ Gigantic SDI-12 bug Add Support for Turner Cyclops ### Added + - **Sensor:** Add support for all standard configurations of the [Turner Cyclops-7F submersible fluorometer](https://www.turnerdesigns.com/cyclops-7f-submersible-fluorometer) ### Fixed + - **Documentation:** Fix some minor Doxygen warnings - **Documentation:** Small grammar fixes - **Documentation:** Fixes in the EnviroDIY fork of m.css: @@ -356,6 +394,7 @@ Add Support for Turner Cyclops Fix GitHub Action ### Fixed + - Just fixed an error in the github action to post a release *** @@ -365,6 +404,7 @@ Fix GitHub Action SDI-12 Bug Fix ### Fixed + - Fixed a compiler error for non-concurrent SDI-12 sensors. *** @@ -374,6 +414,7 @@ SDI-12 Bug Fix Update Documentation ### Changed + - Update instructions for examples - Update developer instructions @@ -384,6 +425,7 @@ Update Documentation Multiple new Sensors and Workflows ### Changed + - Complete re-styling of the Doxygen output to be similar to envirodiy.org - Add enourmous amounts of documentation - Improved explanations and added walkthrough of menu a la carte example @@ -393,6 +435,7 @@ Multiple new Sensors and Workflows - NOTE: Setting the build flag disables concurrent measurements for *ALL* SDI-12 sensors! ### Added + - **Sensor:** PaleoTerra Redox sensors - **Sensor:** Northern Widget Tally Counters - **Sensor:** simple analog electrical conductance sensors @@ -405,6 +448,7 @@ Multiple new Sensors and Workflows - Support software I2C or secondary hardware I2C for all sensors possible ### Known Issues + - The instructions for using most of the examples are out of date. *** @@ -416,21 +460,23 @@ Styling & Doxygen Code Documentation [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3908530.svg)](https://doi.org/10.5281/zenodo.3908530) ### Changed + - Improved C++ code styling elements in every file in the library, to: - Better take advantage of the [Clang](https://clang.llvm.org) compiler and code error [linter](https://en.wikipedia.org/wiki/Lint_(software)) tool; - Generally follow [Clang Format](https://clang.llvm.org/docs/ClangFormat.html) and [Google's coding style guides](https://google.github.io/styleguide/cppguide.html) used with [cpplint](https://en.wikipedia.org/wiki/Cpplint) [linter](https://en.wikipedia.org/wiki/Lint_(software)), which: - includes massive white space changes to improve readability while not changing how the code is executed - Support Doxygen documentation. - Encapsulated modem wake check logic into a function and checking for status using a quick AT ping if no other option is available. - - This will only affect modems/breakouts that depend on a pulse on their wake pin to turn on or off but for whatever reason don't have a separate status pin connected to the mcu. I *do not* recommend this configuration. + - This will only affect modems/breakouts that depend on a pulse on their wake pin to turn on or off but for whatever reason don't have a separate status pin connected to the mcu. I *do not* recommend this configuration. - Always re-set the pin mode of a sensor power pin before attempting to turn it on. - - This could come into play when first attempting to power on a sensor before the initial setup if the pin mode on the sensor power pin was set to input by whatever program the mcu had run prior to running ModularSensors code. + - This could come into play when first attempting to power on a sensor before the initial setup if the pin mode on the sensor power pin was set to input by whatever program the mcu had run prior to running ModularSensors code. ### Added -- **Documentation:** Automated code documentation using [Doxygen](https://www.doxygen.nl/index.html), now available at https://envirodiy.github.io/ModularSensors/ +- **Documentation:** Automated code documentation using [Doxygen](https://www.doxygen.nl/index.html), now available at https://envirodiy.github.io/ModularSensors/ ### Fixed + - Fixed issue where the Digi XBee LTE-M modem did not wake during normal logging mode to transmit data to the publisher. See https://github.com/EnviroDIY/ModularSensors/pull/309#commitcomment-39786167 For more details, see [Pull Request #309: The style sheet](https://github.com/EnviroDIY/ModularSensors/pull/309) @@ -444,6 +490,7 @@ Modem Restructuring [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3693784.svg)](https://doi.org/10.5281/zenodo.3693784) ### Changed + - Restructured modem so that it no longer operates as a sensor. Variables tied to the modem are now effectively calculated variables and all values from the modem will be offset by 1 sending cycle (ie, the signal strength posted will always be the strength from the prior send, not the current one). @@ -456,12 +503,13 @@ More agressive attempts to set clock [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3451413.svg)](https://doi.org/10.5281/zenodo.3451413) ### Changed + - Much more aggressive attempts to set the clock if the time is not reasonable - before 01Sep2019 or after 01Jan2025. - - The LED will flicker and warnings will be sent over the serial port for invalid times at every check. - - The logDataAndPublish function will attempt to synchronize the clock at every measurement until a valid time is received. - - The NIST sync will attempt to open the socket to the daytime server up to 12 times trying to get a valid response. + - The LED will flicker and warnings will be sent over the serial port for invalid times at every check. + - The logDataAndPublish function will attempt to synchronize the clock at every measurement until a valid time is received. + - The NIST sync will attempt to open the socket to the daytime server up to 12 times trying to get a valid response. - Now using automatic network technology and carrier profile for Digi LTE-M XBee3's - - with the current firmware there is not a significant time savings in manually selecting the carrier and manually selecting the carrier gives no options when the relative signal strength of the carriers changes. + - with the current firmware there is not a significant time savings in manually selecting the carrier and manually selecting the carrier gives no options when the relative signal strength of the carriers changes. *** @@ -472,23 +520,27 @@ Watchdogs and More [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3405562.svg)](https://doi.org/10.5281/zenodo.3405562) ### Changed + - Added extra compile tests in the menu a la carte example. - Improvements made to nearly all modem modules - Restore XBee access to resets by TinyGSM ### Added + - A watch-dog timer has been implemented for both the AVR and SAMD21 (and 51) boards to restart the boards in case of failure during logging - - The watch-dog is turned off during sleep to save power, so recovery is only possible if the failure is while the processor is awake. + - The watch-dog is turned off during sleep to save power, so recovery is only possible if the failure is while the processor is awake. - Added support for Meter Terros 11 soil moisture and temperature sensor - Implemented a function to verify that UUID's are at least correctly formed and unique - though it does not verify that they are valid. - Pushing to the master branch of this repo will now also cause a re-run of the travis script that updates the EnviroDIY "Libraries" repository. - Added debugging variables to modems to track how long they are powered/active. ### Fixed + - Fixed all compiler warnings seen with the -Wextra flag (mostly by adding technically-unnecessary-but-visually-helpful braces) - Fixed issue with creating a calculated variable without a UUID ### Known Issues + - polling the AM2315 more frequently than every 2 seconds will now return a bad value (-9999) rather than returning the same value multiple times. This is a reflection of a change in the Adafruit library. The measurement time set for the sensor has always been this long so this issue should never be seen unless you attempt to call get measurement results from the AM2315 without first waiting for the measurement completion. The update function and all variable array functions should behave properly. *** @@ -500,39 +552,44 @@ Modem Simplification [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3255084.svg)](https://doi.org/10.5281/zenodo.3255084) **NOTE: This release is NOT backwards compatible with previous releases.** + - All code must be updated to the current format for modems and time zones to work with this version of the library. ### Changed + - Daily clock synchronization has been moved from midnight to noon. For loggers with solar charging, this should place the extra draw of the modem to do the synchronization to a time of peak charging. - All "send" data functions have been renamed to "publish" to line up with module names. - Updated AM2315 to use most current Adafruit library (2.0.0) ### Added + - **Breaking:** LoggerModem has become a parent class. All modems now exist as separate subclass objects. - - This should greatly simplify creating a modem object in code. - - Currently supported modems: - - Digi XBee and XBee3 cellular modems of all types running in transparent mode - - Digi XBee3 cellular LTE-M modems in bypass mode (this is *in addition* to transparent mode) - - Digi XBee cellular 3G global modems in bypass mode (this is *in addition* to transparent mode) - - Digi XBee Wifi S6B modules - - Sodaq UBee LTE-M (SARA R410M) - - Sodaq UBee 3G (SARA U201) - - Sodaq 2GBee R6/R7 - - Sodaq 2GBee R4, Adafruit Fona, and other SIMComm SIM800 modules - - Botletics and other SIMCom SIM7000 modules - - Dragino, Nimbelink, and other Quectel BG96 modules - - Nimbelink LTE-M Verizon - - Espressif ESP8266 based modules - - The older way of creating a modem object and feeding it wake/sleep functions is no longer supported. + - This should greatly simplify creating a modem object in code. + - Currently supported modems: + - Digi XBee and XBee3 cellular modems of all types running in transparent mode + - Digi XBee3 cellular LTE-M modems in bypass mode (this is *in addition* to transparent mode) + - Digi XBee cellular 3G global modems in bypass mode (this is *in addition* to transparent mode) + - Digi XBee Wifi S6B modules + - Sodaq UBee LTE-M (SARA R410M) + - Sodaq UBee 3G (SARA U201) + - Sodaq 2GBee R6/R7 + - Sodaq 2GBee R4, Adafruit Fona, and other SIMComm SIM800 modules + - Botletics and other SIMCom SIM7000 modules + - Dragino, Nimbelink, and other Quectel BG96 modules + - Nimbelink LTE-M Verizon + - Espressif ESP8266 based modules + - The older way of creating a modem object and feeding it wake/sleep functions is no longer supported. - The real time clock's timezone can now be explicit set (as opposed to setting the logger timezone and the offset between the RTC and the logger) - - The function to set the logger timezone has been renamed from setTimeZone to setLoggerTimeZone. + - The function to set the logger timezone has been renamed from setTimeZone to setLoggerTimeZone. ### Fixed + - Fixed #259 where time zones offset by more than 9 hours from UTC would not work correctly. - Fixed #183 where enabling debugging would cause non AVR boards to crash. - Adjusted some timing parameters for the SIM800 based on testing. ### Known Issues + - polling the AM2315 more frequently than every 2 seconds will now return a bad value (-9999) rather than returning the same value multiple times. This is a reflection of a change in the Adafruit library. The measurement time set for the sensor has always been this long so this issue should never be seen unless you attempt to call get measurement results from the AM2315 without first waiting for the measurement completion. The update function and all variable array functions should behave properly. *** @@ -542,6 +599,7 @@ Modem Simplification Deep debug error ### Fixed + - Fixed minor bug in debugging created in previous release *** @@ -551,11 +609,13 @@ Deep debug error Minor Bugs and Simplified Debugging ### Added + - Gave every header file a unique debugging define statement so each file can be debugged individually by building with the build flag -DMS_xxx_DEBUG where xxx is the file name in upper case. - - Some files also have a "deep" debugging option with -DMS_xxx_DEBUG_DEEP + - Some files also have a "deep" debugging option with -DMS_xxx_DEBUG_DEEP - Created examples for LearnEnviroDIYCode ### Fixed + - Fixed a bug causing modem to not be turned because the processor thought it was on already - Corrected warm-up timing for Yosemitech Sonde - Typo fixes in comments @@ -567,6 +627,7 @@ Minor Bugs and Simplified Debugging Fix write to SD card ### Fixed + - Fixed bug intoduced in 0.21.0 preventing writing to SD card - file must be closed (not sync'ed) *** @@ -578,36 +639,41 @@ Support for all Atlas Scientific I2C sensors, compiler-safe begin functions [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.2586200.svg)](https://doi.org/10.5281/zenodo.2586200) ### Changed + - Eliminated any time-out waits on libraries using the Wire class - Simplified the logger begin function - the removed functionality should be called in individual program setup functions - - Removed clock sync - - Removed logger file creation - - Removed sensor setup + - Removed clock sync + - Removed logger file creation + - Removed sensor setup - Moved the check for setup from the wake function to the startSingleMeasurement function for all sensors - - Previously, the first time the wake was called for a function, the status bit for setup was checked and if the sensor had not been setup, the setup function was called. This will no longer happen the first time the wake function is called, but instead the first time the startSingleMeasurement function is called. The main motivator for the change was the modem which could end up behaving strangely because the setup function actually called the wake function internally. + - Previously, the first time the wake was called for a function, the status bit for setup was checked and if the sensor had not been setup, the setup function was called. This will no longer happen the first time the wake function is called, but instead the first time the startSingleMeasurement function is called. The main motivator for the change was the modem which could end up behaving strangely because the setup function actually called the wake function internally. - Improved example coding for SARA R410 cellular modules ### Added + - **Sensor:** Added full support for all Atlas Scientific EZO curcuits and sensors that support I2C - - CO2 - - DO (dissolved oxygen) - - EC (conductivity) - - ORP (oxidation/reduction potential) - - pH - - RTD (temperature + - CO2 + - DO (dissolved oxygen) + - EC (conductivity) + - ORP (oxidation/reduction potential) + - pH + - RTD (temperature - Created empty constructors for the logger, publisher, variable array, and variable classes and all of their subclasses. For all classes created a corresponding "begin" function to set internal class object values. - - See note for more details: https://github.com/EnviroDIY/ModularSensors/commit/b1a619ed74bc790743bce35b3a4e78a2d2237b22 - - The order of input arguments for all variable objects has changed. For variable subclasses (ie, variables from sensors), there is no change to the user. __**For calculated variable objects, all code must be updated!**__ Please check the structure in the examples! Older code will compile without error but the variable metadata fields will be incorrectly populated. + - See note for more details: https://github.com/EnviroDIY/ModularSensors/commit/b1a619ed74bc790743bce35b3a4e78a2d2237b22 + - The order of input arguments for all variable objects has changed. For variable subclasses (ie, variables from sensors), there is no change to the user. __**For calculated variable objects, all code must be updated!**__ Please check the structure in the examples! Older code will compile without error but the variable metadata fields will be incorrectly populated. - Very preliminary support for SD cards with switchable power ### Removed + - Removed "default" wake/sleep functions from modem. These were non-working skeleton functions. ### Fixed + - Fixed call to a null pointer causing the array's completeUpdate to crash with calculated variables - Fixed source of ADS1x15 dependency ### Known Issues + - Running some I2C sensors on switched power will cause unrecoverable hangs at the first call to any other I2C peripheral (ie, the DS3231 RTC) after sensor power is turned off. This is a hardware problem and is un-fixable within this library. - The sensor class and all of its subclasses still require input arguments in the constructor. @@ -620,14 +686,17 @@ Modem Improvements & ADS1X15 Generalization [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.2579301.svg)](https://doi.org/10.5281/zenodo.2579301) ### Changed + - Modem waits for signal strength return before sending data - Other modem tweaks - Restructuring of data publishers ### Added + - Added ADS1015 as an optional analog to digital converter (ADC) for boards other than the Mayfly ### Fixed + - Fixed bug with ADS1115 for M0/SAM21 *** @@ -637,9 +706,11 @@ Modem Improvements & ADS1X15 Generalization Bug fix and example re-working ### Changed + - Re-works the examples to remove duplication between them. ### Fixed + - Fixes bug in sending data to the WikiWatershed / [Monitor My Watershed](https://monitormywatershed.org/) data sharing portal. *** @@ -649,11 +720,13 @@ Bug fix and example re-working Decreased Data Consumption ### Changed + - Reduced telemetry data consumption (by half in one test) and therefore overall power use, by creating an outgoing text buffer. - Note : the default buffer size is quite large, decrease it to decrease program memory size. - Refactored data publishers as a new class rather than subclasses of loggers ### Added + - Added ThingSpeak support via MQTT (PubSubClient is now a required dependency) - Added support for TI INA219 thanks to @neilh21 (Adafruit INA219 library is now a required dependency) @@ -664,10 +737,12 @@ Decreased Data Consumption Major Update! **NOTE: THIS RELEASE DESTROYS BACKWARDS COMPATIBILITY!!** + - All `.ino` sketch files will need to be updated to follow the updated [examples](https://github.com/EnviroDIY/ModularSensors/tree/master/examples). - All library dependencies will need to be updated to match versions in the [library.json](https://github.com/EnviroDIY/ModularSensors/blob/master/library.json) file. ### Changed + - Improved power management. - Improved stability. - A huge number of other changes, with most of them are documented here: https://github.com/EnviroDIY/ModularSensors/pull/173 @@ -681,9 +756,11 @@ Calculated variables and bug fixes NOTE: This **THIS RELEASE DESTROYS BACKWARDS COMPATIBILITY!!** All `.ino` files will need to be updated to follow the updated examples. ### Added + - Implemented real calculated variables, from PR #153, closing issue #127 (Create generic calculated variables). ### Fixed + - Fixes issue with MaxSonar giving weird readings, due to buffer not being cleared between readings, as described in https://www.envirodiy.org/topic/minor-glitch-reading-maxbotix-mb7389-with-mayfly/ See PR #160 for a full list of improvements and fixes. @@ -695,11 +772,13 @@ See PR #160 for a full list of improvements and fixes. Fixed Longer Logger Intervals and Improved Documentation ### Changed + - **Documentation:** Improved documentation for examples - Applying "sensor testing mode" more consistently in examples - Made variables necessary for sensor testing mode with custom loops public ### Fixed + - Fixed variable type for logging interval from uint8_t to uint16_t allowing consistent logging at intervals greater than 5 minutes *** @@ -709,9 +788,11 @@ Fixed Longer Logger Intervals and Improved Documentation Added sensors and fixed timing bugs ### Changed + - Tweeked code generating csv's and json outputs to allow a modified csv or json to be written to the SD card or posted to data.EnviroDIY.org ### Added + - **Sensor:** Added support for Freescale MPL115A2 pressure sensor - **Sensor:** Added support for Keller Acculevel - **Sensor:** Added support for Yosemitech Y4000 multi-parameter sonde @@ -723,11 +804,13 @@ Added sensors and fixed timing bugs - **Documentation:** Minor corrections to Yosemitech sensor resolution and accuracy. ### Removed + - Removed the "checkForUpdate()" function. When asking for a value from a variable, you now must explicitly state whether you want the variable to ask its parent sensor for an updated value or not. By default, it will _not_ ask the parent sensor to update, but only return the last value received or -9999 if a value has never been received. ### Fixed + - Fixed major bug causing sensors with long stabilization times to not be updated *** @@ -737,13 +820,16 @@ Added sensors and fixed timing bugs Timing Improvements ### Changed + - Major restructuring of sensor status and internal sensor time stamps to improve efficiency when using variables/sensors in arrays - this makes sensor/variable order much less important - Restructured Zebra Tech D-Opto ### Added + - Added MS5803, external voltage, and external tip counter ### Fixed + - Fixed bugs with modem and 5TM *** @@ -753,6 +839,7 @@ Timing Improvements Fixes bugs in description and examples ### Fixed + - Small bug-fixing release *** @@ -762,6 +849,7 @@ Fixes bugs in description and examples Uniformity of missing values, averaging for all sensors ### Changed + - Allows all sensors to be averaged - More uniform return of -9999 for missing/bad values - Better time synching @@ -770,15 +858,18 @@ Uniformity of missing values, averaging for all sensors ## [0.5.4-beta] - 2018-01-18 ### Changed + - Improvements to modem support and debugging - Improved examples - Renaming of a large number of internal variables - Inching closer to full support for SAMD21 (M0/Zero) processors, though still some bugs present. ### Added + - **Sensor:** Added Yosemitech brand sensors which communicate via RS485 ### Fixed + - Clock synchronization fixes - Library metadata and dependency fixes @@ -789,9 +880,11 @@ Uniformity of missing values, averaging for all sensors Beta Release ### Changed + - Changed the interrupt library to EnableInterrupt, which now controls all interrupts. ### Added + - **Sensor:** Added the Apogee SQ-212 PAR sensor. - Added the modem as a "sensor" which can return it's signal strength as a variable. - Added a "debugging" mode, accessible by pushing a button while the checkForDebugMode function is running. @@ -803,6 +896,7 @@ Beta Release Impoved setup functions ### Changed + - Slight rearrangement of setup functions to improve efficiency. *** @@ -812,14 +906,17 @@ Impoved setup functions Another beta release ### Changed + - Shorted time allowed to attempt to turn Bee on/off - Shorted wait for network time to 55 sec (from 60) - Put disconnect step within if block so it only tries to disconnect if it was connected in the first place ### Added + - Added a check that Bee is on before trying to connect to network ### Fixed + - Fixed extra spaces in CSV *** diff --git a/README.md b/README.md index 557731c0f..b5146ebb5 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# ModularSensors +# ModularSensors ___ -## The EnviroDIY ModularSensors Library +## The EnviroDIY ModularSensors Library If you're new to EnviroDIY, I suggest you check out the [Just Getting Started](https://envirodiy.github.io/ModularSensors/page_getting_started.html) section of the documentation! @@ -26,18 +26,18 @@ There is extensive documentation available in the [ModularSensors github pages]( [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) -- [ModularSensors ](#modularsensors-) - - [The EnviroDIY ModularSensors Library ](#the-envirodiy-modularsensors-library-) - - [Supported Sensors ](#supported-sensors-) - - [Data Endpoints ](#data-endpoints-) - - [Supported Cellular/Wifi Modules: ](#supported-cellularwifi-modules-) - - [Contributing ](#contributing-) - - [License ](#license-) - - [Acknowledgments ](#acknowledgments-) +- [ModularSensors](#modularsensors) + - [The EnviroDIY ModularSensors Library](#the-envirodiy-modularsensors-library) + - [Supported Sensors](#supported-sensors) + - [Data Endpoints](#data-endpoints) + - [Supported Cellular/Wifi Modules:](#supported-cellularwifi-modules) + - [Contributing](#contributing) + - [License](#license) + - [Acknowledgments](#acknowledgments) [//]: # ( End GitHub Only ) -## Supported Sensors +## Supported Sensors For some generalized information about attaching sensors to an Arduino style board, see the [Sensor Notes page](https://envirodiy.github.io/ModularSensors/page_sensor_notes.html). @@ -99,7 +99,7 @@ For some generalized information about attaching sensors to an Arduino style boa - [Zebra-Tech D-Opto: dissolved oxygen](https://envirodiy.github.io/ModularSensors/group__sensor__dopto.html) -## Data Endpoints +## Data Endpoints Within ModularSensors, the "dataPublisher" objects add the functionality to send data to remote web services. The currently supported services are the [Monitor My Watershed data portal](http://data.envirodiy.org/), [ThingSpeak](https://thingspeak.com/), and the [Ubidots IoT platform](https://ubidots.com). @@ -111,7 +111,7 @@ The currently supported services are the [Monitor My Watershed data portal](http [//]: # ( @todo Page on Data Endpoints ) -## Supported Cellular/Wifi Modules: +## Supported Cellular/Wifi Modules: For information common to all modems and for tables of the proper class, baud rate, and pins to uses, see the [Modem Notes page](https://envirodiy.github.io/ModularSensors/page_modem_notes.html). @@ -131,7 +131,7 @@ For information common to all modems and for tables of the proper class, baud ra - u-blox 2G, 3G, and 4G, including the [Sodaq 3GBee](https://envirodiy.github.io/ModularSensors/group__modem__ubee__3g.html) -## Contributing +## Contributing Open an [issue](https://github.com/EnviroDIY/ModularSensors/issues) to suggest and discuss potential changes/additions. Feel free to open issues about any bugs you find or any sensors you would like to have added. @@ -141,14 +141,14 @@ This library is built to fully take advantage of Objecting Oriented Programing ( There is _extensive_ documentation on our [github pages](https://envirodiy.github.io/ModularSensors/index.html) and an _enormous_ number of comments and debugging printouts in the code itself to help you get going. -## License +## License Software sketches and code are released under the BSD 3-Clause License -- See [LICENSE.md](https://github.com/EnviroDIY/ModularSensors/blob/master/LICENSE.md) file for details. Documentation is licensed as [Creative Commons Attribution-ShareAlike 4.0](https://creativecommons.org/licenses/by-sa/4.0/) (CC-BY-SA) copyright. Hardware designs shared are released, unless otherwise indicated, under the [CERN Open Hardware License 1.2](http://www.ohwr.org/licenses/cern-ohl/v1.2) (CERN_OHL). -## Acknowledgments +## Acknowledgments [EnviroDIY](http://envirodiy.org/)â„¢ is presented by the Stroud Water Research Center, with contributions from a community of enthusiasts sharing do-it-yourself ideas for environmental science and monitoring. [Sara Damiano](https://github.com/SRGDamia1) is the primary developer of the EnviroDIY ModularSensors library, with input from many [other contributors](https://github.com/EnviroDIY/ModularSensors/graphs/contributors). diff --git a/docs/FAQ/Arduino-Streams.md b/docs/FAQ/Arduino-Streams.md index 51b067d0e..f1de3c8dd 100644 --- a/docs/FAQ/Arduino-Streams.md +++ b/docs/FAQ/Arduino-Streams.md @@ -1,4 +1,4 @@ -# Notes on Arduino Streams and Software Serial +# Notes on Arduino Streams and Software Serial [//]: # ( @tableofcontents ) @@ -34,7 +34,7 @@ This is not a bug that will be fixed. See the section on [Processor/Board Compatibility](https://envirodiy.github.io/ModularSensors/page_processor_compatibility.html) for more specific notes on what serial ports are available on the various supported processors. -## Hardware Serial +## Hardware Serial For stream communication, **hardware serial** should _always_ be your first choice, if your processor has enough hardware serial ports. Hardware serial ports are the most stable and have the best performance of any of the other streams. @@ -51,7 +51,7 @@ HardwareSerial* streamName = &Serial; ``` -## AltSoftSerial +## AltSoftSerial If the [proper pins](https://www.pjrc.com/teensy/td_libs_AltSoftSerial.html) are available, **[AltSoftSerial](https://github.com/PaulStoffregen/AltSoftSerial)** by Paul Stoffregen is also superior to SoftwareSerial, especially at slow baud rates. AltSoftSerial is compatible with ModularSensors "out of the box" - that is, you don't need and modifications to the library or extra defines or build flags to make it work. @@ -69,7 +69,7 @@ AltSoftSerial streamName. ``` -## NeoSWSerial +## NeoSWSerial Another possible serial port emulator is [NeoSWSerial](https://github.com/SRGDamia1/NeoSWSerial). While not as stable as AltSoftSerial, it supports using any pin with pin change interrupts for communication. @@ -110,7 +110,7 @@ enableInterrupt(rx_pin, neoSSerial1ISR, CHANGE); ``` -## Neutered SoftwareSerial +## Neutered SoftwareSerial [The EnviroDIY modified version of SoftwareSerial](https://github.com/EnviroDIY/SoftwaterSerial_ExternalInts) removes direct interrupt control from the SoftwareSerial library, making it dependent on another interrupt library, but able to be compiled with ModularSensors. This is, _by far_, the _least_ stable serial port option and should only be used on sensors that are not very picky about the quality of the serial stream or that only require one-way communication (ie, only posting data rather than needing to receive commands). @@ -137,7 +137,7 @@ enableInterrupt(rx_pin, SoftwareSerial_ExtInts::handle_interrupt, CHANGE); ``` -## SAMD SERCOMs +## SAMD SERCOMs Example code for creating more serial ports on an Adafruit feather M0 using the SERCOMs is available [in the menu a la carte example](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_samd_serial_ports). diff --git a/docs/FAQ/Code-Debugging.md b/docs/FAQ/Code-Debugging.md index 7fd708768..f4a117638 100644 --- a/docs/FAQ/Code-Debugging.md +++ b/docs/FAQ/Code-Debugging.md @@ -1,4 +1,4 @@ -# In-Library Debugging +# In-Library Debugging For intense _code_ debugging for any individual component of the library (sensor communication, modem communication, variable array functions, etc), open the source file header (\*.h), for that component. Find the line `// #define DEBUGGING_SERIAL_OUTPUT xxxxx`, where xxxxx is the name of a serial output (ie, Serial or USBSerial). diff --git a/docs/FAQ/Deceasing-Memory-Use.md b/docs/FAQ/Deceasing-Memory-Use.md index 65d4f18a6..cf5999590 100644 --- a/docs/FAQ/Deceasing-Memory-Use.md +++ b/docs/FAQ/Deceasing-Memory-Use.md @@ -1,4 +1,4 @@ -# Decreasing Memory Footprint +# Decreasing Memory Footprint There are things you could do to decrease memory use. diff --git a/docs/FAQ/Developer-Setup.md b/docs/FAQ/Developer-Setup.md index 19db0b93c..2ece6a18e 100644 --- a/docs/FAQ/Developer-Setup.md +++ b/docs/FAQ/Developer-Setup.md @@ -1,4 +1,4 @@ -# Developer Setup +# Developer Setup If you want to fork this repository and work with it, you'll need to set PlatformIO up a bit differently than you would to merely use this library. @@ -41,7 +41,7 @@ check_flags = clangtidy: --checks=-* ; deep search for dependencies, evalulating preprocessor conditionals lib_ldf_mode = deep+ -; look for the library director +; look for the library directory lib_extra_dirs = . ; We have to ignore these folders or PlatformIO will double count all the dependencies lib_ignore = diff --git a/docs/FAQ/Power-Parasites.md b/docs/FAQ/Power-Parasites.md index 5d7c907c5..d22931f99 100644 --- a/docs/FAQ/Power-Parasites.md +++ b/docs/FAQ/Power-Parasites.md @@ -1,4 +1,4 @@ -# Power Draw over Data Lines +# Power Draw over Data Lines When deploying a logger out into the wild and depending on only battery or solar charging, getting the power draw from sensors to be as low as possible is crucial. This library assumes that the main power/Vcc supply to each sensor can be turned on by setting its powerPin high and off by setting its powerPin low. diff --git a/docs/FAQ/Processor-Compatibility.md b/docs/FAQ/Processor-Compatibility.md index 73c153218..9cd49bcce 100644 --- a/docs/FAQ/Processor-Compatibility.md +++ b/docs/FAQ/Processor-Compatibility.md @@ -1,4 +1,4 @@ -# Processor Compatibility +# Processor Compatibility [//]: # ( @tableofcontents ) @@ -16,7 +16,7 @@ [//]: # ( End GitHub Only ) -## AtMega1284p (EnviroDIY Mayfly, Sodaq Mbili, Mighty 1284) +## AtMega1284p (EnviroDIY Mayfly, Sodaq Mbili, Mighty 1284) The [EnviroDIY Mayfly](https://envirodiy.org/mayfly/) _is_ the test board for this library. _Everything_ is designed to work with this processor. @@ -42,7 +42,7 @@ Pin 12 should not be used while using AltSoftSerial on the Mighty 1284. - Any digital pin can be used with NeoSWSerial, SoftwareSerial_ExtInts, or SDI-12. ___ -## AtSAMD21 (Arduino Zero, Adafruit Feather M0, Sodaq Autonomo) +## AtSAMD21 (Arduino Zero, Adafruit Feather M0, Sodaq Autonomo) Fully supported [Datasheet Summary](https://github.com/EnviroDIY/ModularSensors/wiki/Processor-Datasheets/Atmel-SAMD21-Datasheet-Summary.pdf) @@ -77,7 +77,7 @@ Otherwise, you will have to rely on lights on your alert pin or your modem to ve Turn off the debugging and double-tap to reset and reprogram if this happens. ___ -## AtMega2560 (Arduino Mega) +## AtMega2560 (Arduino Mega) Should be fully functional, but untested. - An external DS3231 or DS3232 RTC is required. @@ -90,7 +90,7 @@ Pins 44 and 45 cannot be used while using AltSoftSerial on the AtMega2560. - Pins 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), and A15 (69) can be used with NeoSWSerial, SoftwareSerial_ExtInts, or SDI-12. ___ -## AtMega644p (Sanguino) +## AtMega644p (Sanguino) Should be fully functional, but untested. @@ -105,7 +105,7 @@ Pin 12 cannot be used while using AltSoftSerial on the AtMega644p. - Any digital pin can be used with NeoSWSerial, SoftwareSerial_ExtInts, or SDI-12. ___ -## AtMega328p (Arduino Uno, Duemilanove, LilyPad, Mini, Seeeduino Stalker, etc) +## AtMega328p (Arduino Uno, Duemilanove, LilyPad, Mini, Seeeduino Stalker, etc) All functions are supported, but processor doesn't have sufficient power to use all of the functionality of the library. You will only be able to use a small number of sensors at one time and may not be able to log data. @@ -121,7 +121,7 @@ Pin 10 cannot be used while using AltSoftSerial on the AtMega328p. - Any digital pin can be used with NeoSWSerial, SoftwareSerial_ExtInts, or SDI-12. ___ -## AtMega32u4 (Arduino Leonardo/Micro, Adafruit Flora/Feather, etc) +## AtMega32u4 (Arduino Leonardo/Micro, Adafruit Flora/Feather, etc) All functions are supported, but processor doesn't have sufficient power to use all of the functionality of the library. You will only be able to use a small number of sensors at one time and may not be able to log data. @@ -143,7 +143,7 @@ If you need to debug, I recommend using a serial port monitor like Tera Term whi Otherwise, you will have to rely on lights on your alert pin or your modem to verify the processor is waking/sleeping properly. ___ -## Unsupported Processors +## Unsupported Processors - **ESP8266/ESP32** - Supported _only_ as a communications module (modem) with the default AT command firmware, not supported as an independent controller - **AtSAM3X (Arduino Due)** - Unsupported at this time due to clock and sleep issues. diff --git a/docs/General-Sensor-Notes.md b/docs/General-Sensor-Notes.md index b7dac75da..5fc5bfef0 100644 --- a/docs/General-Sensor-Notes.md +++ b/docs/General-Sensor-Notes.md @@ -1,4 +1,4 @@ -# Notes about Sensors +# Notes about Sensors There are a number of sensors supported by this library. Depending on the sensor, it may communicate with the Arduino board using as a serial peripheral interface (SPI), inter-integrated circuit (I2C, also called "Wire," "Two Wire", or "TWI"), or some type of universal synchronous/asynchronous receiver/transmitter (UART/USART, or simply "serial") protocol. diff --git a/docs/Getting-Started/Getting-Started.md b/docs/Getting-Started/Getting-Started.md index e133a3e1f..b252b9306 100644 --- a/docs/Getting-Started/Getting-Started.md +++ b/docs/Getting-Started/Getting-Started.md @@ -1,4 +1,4 @@ -# Getting Started +# Getting Started [//]: # ( @tableofcontents ) @@ -18,7 +18,7 @@ Note: These instructions pertain almost entirely to using this specific library. There is an [extensive manual](https://www.envirodiy.org/mayfly-sensor-station-manual/) , set of [appendices](https://www.envirodiy.org/mayfly-sensor-station-manual/appendices/), and [video tutorials](https://www.envirodiy.org/videos/) for planning, installing, and maintaining a stream-side sensor station on the EnviroDIY website. -## IDE and Driver Installation +## IDE and Driver Installation To interface with your board and send it programs, you'll need to install drivers and an [IDE](https://en.wikipedia.org/wiki/Integrated_development_environment) or editor with a compiler on your computer. @@ -44,7 +44,7 @@ To access the menu, click the button that looks like a bug face on the left in V You create new "projects" in PlatformIO from the PlatformIO home page. That home page can be accessed from the PlatformIO menu. -## Library Installation +## Library Installation Before you can use this library, you'll need to install it and all of its [dependencies](https://github.com/EnviroDIY/ModularSensors/wiki/Library-Dependencies) so your compiler in the IDE can find them. Because this library has a large number of dependencies, I, again, _very, **very** strongly_ suggest using [PlatformIO](https://platformio.org/). @@ -52,7 +52,7 @@ If you use PlatformIO, the library will automatically be installed when you list If you really must use the Arduino IDE, this library and all is dependencies can be downloaded in one large zip file [here](https://github.com/EnviroDIY/Libraries/blob/master/libraries.zip?raw=true). -## Setting the Clock +## Setting the Clock Most of this library's functionality depends on having a working DS3231 real time clock attached to your Arduino, so the first thing you need to do is get the time right. For the rank beginners out there; I feel your pain. @@ -85,7 +85,7 @@ You shouldn't have to open or modify the program at all. - Your clock should be set! -## Writing Your Logger Program +## Writing Your Logger Program The set-up in for your logger program PlatformIO is pretty simple: @@ -117,7 +117,7 @@ The download only happens once. - If the build succeeds, you're ready to move on. -## Modifying the Examples +## Modifying the Examples There are a number of examples in the [examples](https://github.com/EnviroDIY/ModularSensors/tree/master/examples) folder for different logger functionalities. If you are unsure which to use, the "menu_a_la_carte" example has code in it for every possible sensor and modem. @@ -155,7 +155,7 @@ Because each sensor outputs temperature and we don't want to waste cellular data This example also shows how to stop power draw from an RS485 adapter with automatic flow detection. -## Deploying your Station +## Deploying your Station To start getting data from the wild, you'll need some [stuff](https://github.com/EnviroDIY/ModularSensors/wiki/Physical-Dependencies) to power your logger and keep it safe from the elements. There are [video instructions](https://www.envirodiy.org/videos/) on the EnviroDIY website showing how to prepare and install a typical steam-side logger box and seniors. diff --git a/docs/Getting-Started/Library-Dependencies.md b/docs/Getting-Started/Library-Dependencies.md index e182a4cc6..24b82c061 100644 --- a/docs/Getting-Started/Library-Dependencies.md +++ b/docs/Getting-Started/Library-Dependencies.md @@ -1,4 +1,4 @@ -# Library Dependencies +# Library Dependencies In order to support multiple functions and sensors, there are quite a lot of sub-libraries that this library depends on. _Even if you do not use the modules, you must have all of the dependencies installed for the library itself to properly compile._ diff --git a/docs/Getting-Started/Physical-Dependencies.md b/docs/Getting-Started/Physical-Dependencies.md index 3adc2bfe4..d09693465 100644 --- a/docs/Getting-Started/Physical-Dependencies.md +++ b/docs/Getting-Started/Physical-Dependencies.md @@ -1,4 +1,4 @@ -# Physical Dependencies +# Physical Dependencies This library is designed for wireless, solar-powered environmental data logging applications, that is, to log data from many physical sensors and to put the processor and all peripherals to sleep to conserver power between readings. The most banal functions of the library require only an AVR or SAMD processor, but making real use of this library requires: diff --git a/docs/Getting-Started/Terminology.md b/docs/Getting-Started/Terminology.md index 603d8afff..1ffbff081 100644 --- a/docs/Getting-Started/Terminology.md +++ b/docs/Getting-Started/Terminology.md @@ -1,6 +1,6 @@ -# Library Terminology +# Library Terminology -## Terms +## Terms Within this library, a Sensor, a Variable, and a Logger mean very specific things: @@ -20,7 +20,7 @@ Within this library, a Sensor, a Variable, and a Logger mean very specific thing [//]: # ( End GitHub Only ) -### Sensor +### Sensor A Sensor is some sort of device that is capable of taking one or more measurements using some sort of method. Most often we can think of these as probes or other instruments that can give back information about the world around them. @@ -31,7 +31,7 @@ They _**must**_ be capable of returning the value of their readings to a logger The detailed Sensor class documentation is here: https://envirodiy.github.io/ModularSensors/class_sensor.html -### Variable +### Variable A Variable is a result value taken by a Sensor _or_ calculated from the results of one or more sensors. It is characterized by a name (what it is a measurement of), a unit of measurement, and a resolution. @@ -50,14 +50,14 @@ The Variable class documentation is here: https://envirodiy.github.io/ModularSe Variables are grouped together into VariableArrays. The VariableArray class documentation is here: https://envirodiy.github.io/ModularSensors/class_variable_array.html -### Logger +### Logger A logger is a circuit board with a processor or microcontroller unit (MCU) that can control all functions of the modem and sensors that are attached to it and save the values of all variables measured by those sensors to an attached SD card. In this library, all loggers are Arduino-style small processor circuit boards. The Logger class documentation is here: https://envirodiy.github.io/ModularSensors/class_logger.html -### Modem +### Modem ![](https://en.wikipedia.org/wiki/Modem#/media/File:Analogue_modem_-_acoustic_coupler.jpg) @@ -72,7 +72,7 @@ All loggerModem functions are heavily dependent on the [TinyGSM](https://github. The loggerModem class documentation is available here: https://envirodiy.github.io/ModularSensors/classlogger_modem.html -### DataPublisher +### DataPublisher Unlike the other components, a dataPublisher object doesn't represent any physical device. It's an object only in the sense of object oriented programming - not something you could hold. @@ -81,7 +81,7 @@ Within the functioning of the library, the dataPublisher "watches" the logger fo The dataPublisher class documentation is available here: https://envirodiy.github.io/ModularSensors/classdata_publisher.html -## Library Structure +## Library Structure This library is built to fully take advantage of Objecting Oriented Programing (OOP) approaches. This means there are a number of base abstract classes with virtual functions and then many more daughter classes which inherit the functions of their parents and implement others themselves. diff --git a/docs/Modem-Notes.md b/docs/Modem-Notes.md index 4a5c841cb..633d5cc72 100644 --- a/docs/Modem-Notes.md +++ b/docs/Modem-Notes.md @@ -1,4 +1,4 @@ -# Notes about Modems +# Notes about Modems [//]: # ( @tableofcontents ) @@ -18,7 +18,7 @@ If you are having trouble, please see the pages for the specific modems and the TinyGSM [getting started](https://github.com/vshymanskyy/TinyGSM#getting-started) and [troubleshooting](https://github.com/vshymanskyy/TinyGSM#troubleshooting) sections. -## Summary of Classes to use for Various Manufactured Modules +## Summary of Classes to use for Various Manufactured Modules | Module | Class | | :-------------------------------------------: | :----------------------------------------------: | @@ -56,7 +56,7 @@ If you are having trouble, please see the pages for the specific modems and the *** -## Default baud rates of supported modules +## Default baud rates of supported modules | Module | Default Baud Rate | | :--------------------------------: | :------------------------------------------------------: | @@ -71,7 +71,7 @@ If you are having trouble, please see the pages for the specific modems and the *** -## Power Requirements of Supported Modems +## Power Requirements of Supported Modems @note Standard USB ports and most Arduino boards (including the Mayfly) are only cabable of supplying **500mA** of power. Any model that requires a higher level of current (almost all of them) should be given a separate power supply than the main processor. @@ -105,7 +105,7 @@ Most modules are capable of serial communication and some level of functionality *** -## Sleep and Reset Pin Labels +## Sleep and Reset Pin Labels | Module | Status Pin Label | Reset Label | Wake / Sleep Request | | :---------------------------: | :-----------------------------------------: | :---------: | :-----------------------------------------: | @@ -130,7 +130,7 @@ Most modules are capable of serial communication and some level of functionality *** -## Pin Numbers to Use when Connecting to a Mayfly 0.x +## Pin Numbers to Use when Connecting to a Mayfly 0.x Here are the pin numbers to use for modules that can be attached directly to an EnviroDIY Mayfly v0.3, 0.4, 0.5, 0.5b, or 0.5c using its Bee socket. @@ -178,7 +178,7 @@ modem.setModemResetLevel(HIGH); *** -## Pin Numbers to Use when Connecting to a Mayfly 1.x +## Pin Numbers to Use when Connecting to a Mayfly 1.x Here are the pin numbers to use for modules that can be attached directly to an EnviroDIY Mayfly v1.0 or 1.1 using its Bee socket. diff --git a/examples/DRWI_2G/ReadMe.md b/examples/DRWI_2G/ReadMe.md index 38ad72709..668db9cb6 100644 --- a/examples/DRWI_2G/ReadMe.md +++ b/examples/DRWI_2G/ReadMe.md @@ -1,4 +1,4 @@ -# DRWI 2G Sites +# DRWI 2G Sites This code was used for DRWI monitoring stations in 2016-2022. The 2G GPRSbee cellular boards no longer function in the USA, so this code should not be used and is only provided to archival and reference purposes. @@ -29,13 +29,13 @@ _______ _______ -# Unique Features of the DRWI 2G Example +# Unique Features of the DRWI 2G Example - Specifically for sites within the Delaware River Watershed Initiative. - Uses a Sodaq 2GBee for live data. -# To Use this Example +# To Use this Example -## Prepare and set up PlatformIO +## Prepare and set up PlatformIO - Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/DRWI_CitSci/platformio.ini) file in the examples/DRWI_CitSci folder on GitHub. @@ -46,7 +46,7 @@ _______ - Move it into the src directory of your project. - Delete main.cpp in that folder. -## Set the logger ID +## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -54,7 +54,7 @@ _______ const char *LoggerID = "XXXX"; ``` -## Set the calibration coefficients for the Campbell OBS3+ +## Set the calibration coefficients for the Campbell OBS3+ - The OBS3+ ships with a calibration certificate; you need this sheet! - Change _**all**_ of the the `0.000E+00` and `1.000E+00` values in this section of code to the values on that calibration sheet. Use numbers from the side of the calibration sheet that shows the calibration in _**volts**_. @@ -83,7 +83,7 @@ const float OBSHigh_C = 0.000E+00; // "C" value [*high* range] CampbellOBS3 osb3high(OBS3Power, OBSHighADSChannel, OBSHigh_A, OBSHigh_B, OBSHigh_C, ADSi2c_addr, OBS3numberReadings); ``` -## Set the universally universal identifiers (UUID) for each variable +## Set the universally universal identifiers (UUID) for each variable - Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - Find and click the white "View Token UUID List" button above the small map on your site page - **VERY CAREFULLY** check that the variables are in exactly the same order as in the variable array: @@ -122,7 +122,7 @@ const char* samplingFeature = "12345678-abcd-1234-ef00-1234567890ab"; // Sampli ``` -## Upload! +## Upload! - Test everything at home **before** deploying out in the wild! _______ diff --git a/examples/DRWI_DigiLTE/ReadMe.md b/examples/DRWI_DigiLTE/ReadMe.md index f7393cd92..d101cd724 100644 --- a/examples/DRWI_DigiLTE/ReadMe.md +++ b/examples/DRWI_DigiLTE/ReadMe.md @@ -1,4 +1,4 @@ -# DRWI Digi LTE Sites +# DRWI Digi LTE Sites This example uses the sensors and equipment common to older stations (2016-2020) deployed by groups participating in the DRWI Citizen Science project with the Stroud Water Research Center. It includes a Meter Hydros21 CTD (formerly know as a Decagon), a Campbell OBS3+ (Turbidity), and a Digi XBee3 LTE-M cellular board for communication. The Digi LTE module also required the use of a EnviroDIY LTEbee Adapter board (discontinued in 2021). The Digi LTE modules are no longer recommended for use and have been replace by the EnviroDIY LTEbee in all DRWI-SWRC-managed stations. @@ -29,13 +29,13 @@ _______ _______ -# Unique Features of the DRWI Digi LTE Example +# Unique Features of the DRWI Digi LTE Example - Specifically for sites within the Delaware River Watershed Initiative. - Uses a Digi XBee3 LTE-M for live data. -# To Use this Example +# To Use this Example -## Prepare and set up PlatformIO +## Prepare and set up PlatformIO - Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/DRWI_DigiLTE/platformio.ini) file in the examples/DRWI_DigiLTE folder on GitHub. @@ -46,7 +46,7 @@ _______ - Move it into the src directory of your project. - Delete main.cpp in that folder. -## Set the logger ID +## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -54,7 +54,7 @@ _______ const char *LoggerID = "XXXX"; ``` -## Set the calibration coefficients for the Campbell OBS3+ +## Set the calibration coefficients for the Campbell OBS3+ - The OBS3+ ships with a calibration certificate; you need this sheet! - Change _**all**_ of the the `0.000E+00` and `1.000E+00` values in this section of code to the values on that calibration sheet. Use numbers from the side of the calibration sheet that shows the calibration in _**volts**_. @@ -83,7 +83,7 @@ const float OBSHigh_C = 0.000E+00; // "C" value [*high* range] CampbellOBS3 osb3high(OBS3Power, OBSHighADSChannel, OBSHigh_A, OBSHigh_B, OBSHigh_C, ADSi2c_addr, OBS3numberReadings); ``` -## Set the universally universal identifiers (UUID) for each variable +## Set the universally universal identifiers (UUID) for each variable - Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - Find and click the white "View Token UUID List" button above the small map on your site page - **VERY CAREFULLY** check that the variables are in exactly the same order as in the variable array: @@ -122,7 +122,7 @@ const char* samplingFeature = "12345678-abcd-1234-ef00-1234567890ab"; // Sampli ``` -## Upload! +## Upload! - Test everything at home **before** deploying out in the wild! _______ diff --git a/examples/DRWI_Mayfly1/ReadMe.md b/examples/DRWI_Mayfly1/ReadMe.md index 6afa25eed..f814a8b70 100644 --- a/examples/DRWI_Mayfly1/ReadMe.md +++ b/examples/DRWI_Mayfly1/ReadMe.md @@ -1,4 +1,4 @@ -# DRWI Sites with a Mayfly 1.x and EnviroDIY LTE Bees +# DRWI Sites with a Mayfly 1.x and EnviroDIY LTE Bees Example sketch for using the EnviroDIY SIM7080G LTE cellular module with an EnviroDIY Mayfly Data Logger. This example uses the sensors and equipment used by most groups participating in the DRWI (Delaware River Watershed Initiative) Citizen Science project with the Stroud Water Research Center. It includes a Meter Hydros 21 (CTD) and a SIM7080G-based EnviroDIY LTEbee for communication. This examples also makes use of the on-board light, temperature, and humidity sensors on the Mayfly 1.x. The results are saved to the SD card and posted to the Monitor My Watershed data portal. Only to be used with newer Mayfly v1.0 and v1.1 boards. @@ -17,7 +17,7 @@ The EnviroDIY LTE SIM7080 module includes 2 antennas in the package. The small The included cell antenna works best in high-signal-strength areas. For most remote areas and logger deployments, we suggest a larger LTE antenna, like the W3907B0100 from PulseLarsen (Digikey 1837-1003-ND or Mouser 673-W3907B0100) -Users purchasing a new Hydros21 CTD sensor will need to change the SDI-12 address of the sensor in order to use this sketch. Full instructions for using this sketch as part of a monitoring station can be found in the EnviroDIY Monitoring Station Manual. +Users purchasing a new Hydros21 CTD sensor will need to change the SDI-12 address of the sensor in order to use this sketch. Full instructions for using this sketch as part of a monitoring station can be found in the EnviroDIY Monitoring Station Manual. _______ [//]: # ( @tableofcontents ) @@ -32,7 +32,7 @@ _______ _______ -# Unique Features of the DRWI Mayfly 1.x LTE Example +# Unique Features of the DRWI Mayfly 1.x LTE Example - Specifically for sites within the Delaware River Watershed Initiative. - Uses a EnviroDIY LTE Bee based on the SIMCom SIM7080G diff --git a/examples/DRWI_Mayfly1_WiFi/ReadMe.md b/examples/DRWI_Mayfly1_WiFi/ReadMe.md index 511a36e48..9641d4c94 100644 --- a/examples/DRWI_Mayfly1_WiFi/ReadMe.md +++ b/examples/DRWI_Mayfly1_WiFi/ReadMe.md @@ -1,4 +1,4 @@ -# DRWI Sites with a Mayfly 1.x and EnviroDIY ESP32 WiFi Bees +# DRWI Sites with a Mayfly 1.x and EnviroDIY ESP32 WiFi Bees Example sketch for using the EnviroDIY ESP32 WiFi cellular module with an EnviroDIY Mayfly Data Logger. The exact hardware configuration used in this example: @@ -12,7 +12,7 @@ Mayfly v0.5b has the Bee socket constantly powered, therefore using "-1" is the The WiFi antenna is built into the ESP32 Bee - no external antenna is needed -Be sure to edit lines 101 and 102 to enter your Wifi access point name and password, and edit the UUID section beginning at line 200 with the correct UUIDs from your specific site on MonitorMyWatershed. +Be sure to edit lines 101 and 102 to enter your Wifi access point name and password, and edit the UUID section beginning at line 200 with the correct UUIDs from your specific site on MonitorMyWatershed. _______ @@ -28,7 +28,7 @@ _______ _______ -# Unique Features of the DRWI Mayfly 1.x WiFi Example +# Unique Features of the DRWI Mayfly 1.x WiFi Example - Specifically for sites within the Delaware River Watershed Initiative. - Uses a EnviroDIY WiFi Bee based on the Espressif ESP32-WROOM-32 diff --git a/examples/DRWI_NoCellular/ReadMe.md b/examples/DRWI_NoCellular/ReadMe.md index 1ebd61948..9ca23963e 100644 --- a/examples/DRWI_NoCellular/ReadMe.md +++ b/examples/DRWI_NoCellular/ReadMe.md @@ -1,4 +1,4 @@ -# DRWI sites with no Cellular Service +# DRWI sites with no Cellular Service This is the code example that should be used for all groups working with the Stroud Water Research Center within the Delaware River Watershed Initiative. This example should be used in cases where no cellular service of any kind is available and the data will only be logged on the SD card. @@ -34,13 +34,13 @@ _______ _______ -# Unique Features of the DRWI LTE Example +# Unique Features of the DRWI LTE Example - Specifically for sites within the Delaware River Watershed Initiative. - Does *not* include any live data uploads. -# To Use this Example +# To Use this Example -## Prepare and set up PlatformIO +## Prepare and set up PlatformIO - Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/DRWI_NoCellular/platformio.ini) file in the examples/DRWI_NoCellular folder on GitHub. @@ -51,7 +51,7 @@ _______ - Move it into the src directory of your project. - Delete main.cpp in that folder. -## Set the logger ID +## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -59,7 +59,7 @@ _______ const char *LoggerID = "XXXX"; ``` -## Set the calibration coefficients for the Campbell OBS3+ +## Set the calibration coefficients for the Campbell OBS3+ - The OBS3+ ships with a calibration certificate; you need this sheet! - Change _**all**_ of the the `0.000E+00` and `1.000E+00` values in this section of code to the values on that calibration sheet. Use numbers from the side of the calibration sheet that shows the calibration in _**volts**_. @@ -88,7 +88,7 @@ const float OBSHigh_C = 0.000E+00; // "C" value [*high* range] CampbellOBS3 osb3high(OBS3Power, OBSHighADSChannel, OBSHigh_A, OBSHigh_B, OBSHigh_C, ADSi2c_addr, OBS3numberReadings); ``` -## Set the universally universal identifiers (UUID) for each variable +## Set the universally universal identifiers (UUID) for each variable - Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - Find and click the white "View Token UUID List" button above the small map on your site page - **VERY CAREFULLY** check that the variables are in exactly the same order as in the variable array: @@ -125,7 +125,7 @@ const char* samplingFeature = "12345678-abcd-1234-ef00-1234567890ab"; // Sampli ``` -## Upload! +## Upload! - Test everything at home **before** deploying out in the wild! _______ diff --git a/examples/DRWI_SIM7080LTE/ReadMe.md b/examples/DRWI_SIM7080LTE/ReadMe.md index 2b3e0237f..b3a610ee0 100644 --- a/examples/DRWI_SIM7080LTE/ReadMe.md +++ b/examples/DRWI_SIM7080LTE/ReadMe.md @@ -1,4 +1,4 @@ -# DRWI Sites with EnviroDIY LTE Bees +# DRWI Sites with EnviroDIY LTE Bees The DRWI EnviroDIY LTEbee example uses the sensors and equipment common to older stations (2016-2020) deployed by groups participating in the DRWI Citizen Science project with the Stroud Water Research Center. It includes a Meter Hydros 21 (CTD), a Campbell OBS3+, (Turbidity) and a SIM7080G-based EnviroDIY LTEbee for communication. @@ -31,7 +31,7 @@ _______ _______ -# Unique Features of the DRWI EnviroDIY LTE Example +# Unique Features of the DRWI EnviroDIY LTE Example - Specifically for sites within the Delaware River Watershed Initiative. - Uses a EnviroDIY LTE Bee based on the SIMCom SIM7080G diff --git a/examples/ReadMe.md b/examples/ReadMe.md index 59808ebe4..0a2801fea 100644 --- a/examples/ReadMe.md +++ b/examples/ReadMe.md @@ -1,4 +1,4 @@ -# Examples Using ModularSensors +# Examples Using ModularSensors These example programs demonstrate how to use the modular sensors library. Each example has slightly different functionality. @@ -33,9 +33,9 @@ ___ [//]: # ( @m_footernavigation ) -## Basic Functionality +## Basic Functionality -### Single Sensor +### Single Sensor The single_sensor example shows making use of the unified set of commands to print data from a MaxBotix ultrasonic range finder to the serial port. It also shows creating a calculated variable which is the water depth. @@ -44,7 +44,7 @@ It also shows creating a calculated variable which is the water depth. - [The single sensor example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/single_sensor) -### Simple Logging +### Simple Logging The simple logging example shows how to create multiple sensors, create variables for the sensors in a variable array, and log the data from the sensors to an SD card. @@ -52,7 +52,7 @@ The simple logging example shows how to create multiple sensors, create variable - [The simple logging example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/simple_logging) -### Simple Logging for the Learn EnviroDIY course +### Simple Logging for the Learn EnviroDIY course The simple logging example for the [Learn EnviroDIY programming course](https://envirodiy.github.io/LearnEnviroDIY/) shows how to create multiple sensors, create variables for the sensors in a variable array, and log the data from the sensors to an SD card. It is very similar to the other simple logging example, with just a few extra sensors. @@ -63,9 +63,9 @@ It is very similar to the other simple logging example, with just a few extra se ___ -## Publishing Data +## Publishing Data -### Publishing to Monitor My Watershed +### Publishing to Monitor My Watershed The logging to Monitor My Watershed example uses a Digi XBee in transparent mode to publish data live from a BME280 and Maxim DS18 to the Monitor My Watershed data portal. @@ -73,7 +73,7 @@ The logging to Monitor My Watershed example uses a Digi XBee in transparent mode - [The logging to Monitor My Watershed example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/logging_to_MMW) -### Publishing to ThingSpeak +### Publishing to ThingSpeak The logging to ThingSpeak example uses an ESP8266 to send data to ThingSpeak. It also includes a Meter Hydros 21 (formerly know as a Decagon CTD) and a Campbell OBS3+. @@ -84,9 +84,9 @@ It also includes a Meter Hydros 21 (formerly know as a Decagon CTD) and a Campbe ___ -## Calculations and Complex Logging +## Calculations and Complex Logging -### Barometric Pressure Correction +### Barometric Pressure Correction The barometric pressure correction example demonstrates how to work with calculated variables and calculates water depth by correcting the total pressure measured by a MeaSpec MS5803 with the atmospheric pressure measured by a Bosch BME280 environmental sensor and the temperature measured by a Maxim DS18 temperature probe. @@ -94,7 +94,7 @@ The barometric pressure correction example demonstrates how to work with calcul - [The barometric pressure correction example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/baro_rho_correction) -### Multiple Logging Intervals +### Multiple Logging Intervals The more complicated double logger example using two different logger instances to log data at two different intervals, in this case, an AM3215 logging every minute, while checking the battery voltage only every 5 minutes. This showcases both how to use two different logging instances and how to use some of the functions to set up your own logging loop rather than using the logData() function. @@ -103,7 +103,7 @@ This showcases both how to use two different logging instances and how to use so - [The double logger example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/double_logger) -### Minimizing Cell Data Usage +### Minimizing Cell Data Usage The data saving example is another double logger example, but in this case, both loggers are going at the same interval and the only difference between the loggers is the list of variables. There are two sets of variables, all coming from Yosemitech sensors. @@ -116,9 +116,9 @@ This example also shows how to stop power draw from an RS485 adapter with automa ___ -## DRWI Citizen Science +## DRWI Citizen Science -### DRWI Mayfly 1.x LTE +### DRWI Mayfly 1.x LTE The DRWI Mayfly 1.x LTE example uses the sensors and equipment used by most groups participating in the DRWI (Delaware River Watershed Initiative) Citizen Science project with the Stroud Water Research Center. It includes a Meter Hydros 21 (CTD) and a SIM7080G-based EnviroDIY LTEbee for communication. @@ -128,7 +128,7 @@ The results are saved to the SD card and posted to the Monitor My Watershed data - [Instructions for the Mayfly 1.x LTE DRWI Citizen Science example](https://envirodiy.github.io/ModularSensors/example_drwi_mayfly1.html) - [The LTEG DRWI Citizen Science example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/DRWI_Mayfly1) -### DRWI EnviroDIY LTEbee +### DRWI EnviroDIY LTEbee The DRWI EnviroDIY LTEbee example uses the sensors and equipment common to older stations (2016-2020) deployed by groups participating in the DRWI Citizen Science project with the Stroud Water Research Center. It includes a Meter Hydros 21 (CTD), a Campbell OBS3+, (Turbidity) and a SIM7080G-based EnviroDIY LTEbee for communication. @@ -138,18 +138,18 @@ The only difference between this and the other cellular DRWI examples below is t - [Instructions for the EnviroDIY LTEbee DRWI Citizen Science example](https://envirodiy.github.io/ModularSensors/example_drwi_ediylte.html) - [The EnviroDIY LTE DRWI Citizen Science example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/DRWI_DigiLTE) -### DRWI Digi LTE +### DRWI Digi LTE The DRWI Digi LTE example uses the sensors and equipment common to older stations (2016-2020) deployed by groups participating in the DRWI Citizen Science project with the Stroud Water Research Center. It includes a Meter Hydros 21 (formerly know as a Decagon CTD), a Campbell OBS3+, and a Digi XBee3 LTE-M for communication. The results are saved to the SD card and posted to the Monitor My Watershed data portal. -The only difference between this and the other cellular DRWI examples is the type of modem used. +The only difference between this and the other cellular DRWI examples is the type of modem used. - [Instructions for the Digi LTE DRWI Citizen Science example](https://envirodiy.github.io/ModularSensors/example_drwi_digilte.html) - [The Digi LTE DRWI Citizen Science example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/DRWI_DigiLTE) -### DRWI CitSci (2G) +### DRWI CitSci (2G) The 2G DRWI Citizen Science example uses the sensors and equipment found on older stations used in the DRWI Citizen Science project prior to 2020. The 2G GPRSbee boards no longer function in the USA, so this code should not be used and is only provided to archival and reference purposes. It includes a Meter Hydros 21 (formerly know as a Decagon CTD), a Campbell OBS3+, and a Sodaq GPRSBee for communication. @@ -160,7 +160,7 @@ The only difference between this and the other cellular DRWI examples is the typ - [The 2G DRWI Citizen Science example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/DRWI_CitSci) -### DRWI CitSci No Cellular +### DRWI CitSci No Cellular The DRWI no cellular example uses the sensors and equipment standard to the DRWI Citizen Science project but omits the data publisher for circumstances where there is no cellular signal. It includes a Meter Hydros 21 (CTD) and a Campbell OBS3+ (Turbidity). @@ -172,9 +172,9 @@ The exclusion of the modem and publisher simplifies the code from the other DRWI ___ -## Everything at Once - a la carte +## Everything at Once - a la carte -### Menu a la carte +### Menu a la carte The "menu a la carte" example shows most of the functions of the library in one gigantic program. It has code in it for every possible sensor and modem and for both AVR and SAMD boards. diff --git a/examples/baro_rho_correction/ReadMe.md b/examples/baro_rho_correction/ReadMe.md index 1914527d0..eb37c6e60 100644 --- a/examples/baro_rho_correction/ReadMe.md +++ b/examples/baro_rho_correction/ReadMe.md @@ -1,4 +1,4 @@ -# Calculating Results based on Measured Values +# Calculating Results based on Measured Values This example demonstrates how to work with calculated variables and calculates water depth by correcting the total pressure measured by a MeaSpec MS5803 with the atmospheric pressure measured by a Bosch BME280 environmental sensor and the temperature measured by a Maxim DS18 temperature probe. @@ -25,13 +25,13 @@ _______ _______ -# Unique Features of the Barometric Correction Example +# Unique Features of the Barometric Correction Example - All variables are created and named with their parent sensor (as opposed to being created within the variable array). - There are multiple calculated variables created and used. -# To Use this Example +# To Use this Example -## Prepare and set up PlatformIO +## Prepare and set up PlatformIO - Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/baro_rho_correction/platformio.ini) file in the examples/baro_rho_correction folder on GitHub. @@ -42,7 +42,7 @@ _______ - Move it into the src directory of your project. - Delete main.cpp in that folder. -## Set the logger ID +## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -50,11 +50,11 @@ _______ const char *LoggerID = "XXXX"; ``` -## Set the universally universal identifiers (UUID) for each variable +## Set the universally universal identifiers (UUID) for each variable - Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - For each variable, find the dummy UUID (`"12345678-abcd-1234-ef00-1234567890ab"`) and replace it with the real UUID for the variable. -## Upload! +## Upload! - Test everything at home **before** deploying out in the wild! _______ diff --git a/examples/data_saving/ReadMe.md b/examples/data_saving/ReadMe.md index 4df834614..b689fdd16 100644 --- a/examples/data_saving/ReadMe.md +++ b/examples/data_saving/ReadMe.md @@ -1,4 +1,4 @@ -# Minimizing Cellular Data Use +# Minimizing Cellular Data Use This is another double logger example, but in this case, both loggers are going at the same interval and the only difference between the loggers is the list of variables. There are two sets of variables, all coming from Yosemitech sensors. @@ -27,7 +27,7 @@ _______ _______ -# Unique Features of the Data Saving Example +# Unique Features of the Data Saving Example - Uses AltSoftSerial to create an additional serial port for RS485 communication. - All variables are created and named with their parent sensor (as opposed to being created within the variable array). - Two different variable arrays and loggers are created and used. @@ -37,9 +37,9 @@ _______ - This demonstrates *how* to write the loop out, without using the `logData` functions. - It also shows how to forcibly set serial pins `LOW` at the start and end of the loop in order to prevent power loss through an RS485 adapter. -# To Use this Example +# To Use this Example -## Prepare and set up PlatformIO +## Prepare and set up PlatformIO - Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/data_saving/platformio.ini) file in the examples/data_saving folder on GitHub. @@ -50,7 +50,7 @@ _______ - Move it into the src directory of your project. - Delete main.cpp in that folder. -## Set the logger ID +## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -58,11 +58,11 @@ _______ const char *LoggerID = "XXXX"; ``` -## Set the universally universal identifiers (UUID) for each variable +## Set the universally universal identifiers (UUID) for each variable - Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - For each variable, find the dummy UUID (`"12345678-abcd-1234-ef00-1234567890ab"`) and replace it with the real UUID for the variable. -## Upload! +## Upload! - Test everything at home **before** deploying out in the wild! _______ diff --git a/examples/double_logger/ReadMe.md b/examples/double_logger/ReadMe.md index 5752c99d4..c22e20160 100644 --- a/examples/double_logger/ReadMe.md +++ b/examples/double_logger/ReadMe.md @@ -1,4 +1,4 @@ -# Multiple Time Intervals +# Multiple Time Intervals This is a more complicated example using two different logger instances to log data at two different intervals, in this case, an AM3215 logging every minute, while checking the battery voltage only every 5 minutes. This showcases both how to use two different logging instances and how to use some of the functions to set up your own logging loop rather than using the logData() function. @@ -21,7 +21,7 @@ _______ _______ -# Unique Features of the Double Logger Example +# Unique Features of the Double Logger Example - Two different variable arrays and loggers are created and used. - The Variables for the arrays are created within the array. - There is no variable overlap between the two arrays or loggers. @@ -29,9 +29,9 @@ _______ - This demonstrates *how* to write the loop out, without using the `logData` functions. - This shows which functions are required for each of the two loggers and which can be used in common. -# To Use this Example +# To Use this Example -## Prepare and set up PlatformIO +## Prepare and set up PlatformIO - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/double_logger/platformio.ini) file in the examples/double_logger folder on GitHub. - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. @@ -41,7 +41,7 @@ _______ - Move it into the src directory of your project. - Delete main.cpp in that folder. -## Set the logger ID +## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -49,7 +49,7 @@ _______ const char *LoggerID = "XXXX"; ``` -## Upload! +## Upload! - Test everything at home **before** deploying out in the wild! _______ diff --git a/examples/logging_to_MMW/ReadMe.md b/examples/logging_to_MMW/ReadMe.md index 2663f8cc8..c7e6d4398 100644 --- a/examples/logging_to_MMW/ReadMe.md +++ b/examples/logging_to_MMW/ReadMe.md @@ -1,4 +1,4 @@ -# Sending Data to Monitor My Watershed/EnviroDIY +# Sending Data to Monitor My Watershed/EnviroDIY This sketch reduces menu_a_la_carte.ino to provide an example of how to log to https://monitormywatershed.org/ from two sensors, the BME280 and DS18. To complete the set up for logging to the web portal, the UUIDs for the site and each variable would need to be added to the sketch. @@ -27,13 +27,13 @@ _______ _______ -# Unique Features of the Monitor My Watershed Example +# Unique Features of the Monitor My Watershed Example - A single logger publishes data to the Monitor My Watershed data portal. - Uses a cellular Digi XBee or XBee3 -# To Use this Example +# To Use this Example -## Prepare and set up PlatformIO +## Prepare and set up PlatformIO - Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/logging_to_MMW/platformio.ini) file in the examples/logging_to_MMW folder on GitHub. @@ -44,7 +44,7 @@ _______ - Move it into the src directory of your project. - Delete main.cpp in that folder. -## Set the logger ID +## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -52,11 +52,11 @@ _______ const char *LoggerID = "XXXX"; ``` -## Set the universally universal identifiers (UUID) for each variable +## Set the universally universal identifiers (UUID) for each variable - Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - For each variable, find the dummy UUID (`"12345678-abcd-1234-ef00-1234567890ab"`) and replace it with the real UUID for the variable. -## Upload! +## Upload! - Test everything at home **before** deploying out in the wild! _______ diff --git a/examples/logging_to_ThingSpeak/ReadMe.md b/examples/logging_to_ThingSpeak/ReadMe.md index bc8ee3cb0..a6d51e31b 100644 --- a/examples/logging_to_ThingSpeak/ReadMe.md +++ b/examples/logging_to_ThingSpeak/ReadMe.md @@ -1,4 +1,4 @@ -# Sending data to ThingSpeak +# Sending data to ThingSpeak This shows the use of a "ThingSpeak logger" object. Data is sent to [ThingSpeak](https://thingspeak.com) using MQTT. @@ -21,13 +21,13 @@ _______ _______ -# Unique Features of the ThingSpeak Example +# Unique Features of the ThingSpeak Example - A single logger publishes data to ThingSpeak. - Uses an Espressif ESP8266 to publish data. -# To Use this Example +# To Use this Example -## Prepare and set up PlatformIO +## Prepare and set up PlatformIO - Create a channel on ThingSpeak with fields to receive your data. - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/logging_to_ThingSpeak/platformio.ini) file in the examples/logging_to_ThingSpeak folder on GitHub. @@ -38,7 +38,7 @@ _______ - Move it into the src directory of your project. - Delete main.cpp in that folder. -## Modify the Example +## Modify the Example - Modify logging_to_ThingSpeak.ino to have the modem, sensor, and variable objects that you are interested in. - This example is written for an _ESP8266 (wifi)_ modem. Change this to whatever modem you are using. @@ -63,7 +63,7 @@ const char *thingSpeakChannelID = "######"; // The numeric channel id for your const char *thingSpeakChannelKey = "XXXXXXXXXXXXXXXX"; // The Write API Key for your channel ``` -## Upload! +## Upload! - Test everything at home **before** deploying out in the wild! _______ diff --git a/examples/menu_a_la_carte/ReadMe.md b/examples/menu_a_la_carte/ReadMe.md index a67c77ae7..f27f268d9 100644 --- a/examples/menu_a_la_carte/ReadMe.md +++ b/examples/menu_a_la_carte/ReadMe.md @@ -1,4 +1,4 @@ -# Example showing all possible functionality +# Example showing all possible functionality This shows most of the functionality of the library at once. It has code in it for every possible sensor and modem and for both AVR and SAMD boards. @@ -8,7 +8,7 @@ To create your own code, I recommend starting from a much simpler targeted examp _______ -# Walking Through the Code +# Walking Through the Code [//]: # ( @note ) *NOTE: This walkthrough is intended to be viewed on GitHub pages at https://envirodiy.github.io/ModularSensors/example_menu.html* @@ -151,9 +151,9 @@ ___ [//]: # ( End GitHub Only ) -## Defines and Includes +## Defines and Includes -### Defines for the Arduino IDE +### Defines for the Arduino IDE The top few lines of the examples set defines of buffer sizes and yields needed for the Arduino IDE. That IDE read any defines within the top few lines and applies them as build flags for the processor. This is _not_ standard behavior for C++ (which is what Arduino code really is) - this is a unique aspect of the Arduino IDE. @@ -173,7 +173,7 @@ build_flags = ``` ___ -### Library Includes +### Library Includes Next, include the libraries needed for every program using ModularSensors. @@ -181,9 +181,9 @@ Next, include the libraries needed for every program using ModularSensors. ___ -## Logger Settings +## Logger Settings -### Creating Extra Serial Ports +### Creating Extra Serial Ports This section of the example has all the code to create and link to serial ports for both AVR and SAMD based boards. The EnviroDIY Mayfly, the Arduino Mega, UNO, and Leonardo are all AVR boards. @@ -196,14 +196,14 @@ Most processors have built in dedicated wires for serial communication - "Hardwa See the page on [Arduino streams](@ref page_arduino_streams) for much more detail about serial connections with Arduino processors. _______ -#### AVR Boards +#### AVR Boards Most Arduino AVR style boards have very few (ie, one, or none) dedicated serial ports _available_ after counting out the programming serial port. So to connect anything else, we need to try to emulate the processor serial functionality with a software library. This example shows three possible libraries that can be used to emulate a serial port on an AVR board. -##### AltSoftSerial +##### AltSoftSerial [AltSoftSerial](https://github.com/PaulStoffregen/AltSoftSerial) by Paul Stoffregen is the most accurate software serial port for AVR boards. AltSoftSerial can only be used on one set of pins on each board so only one AltSoftSerial port can be used. @@ -213,7 +213,7 @@ See the [processor compatibility](@ref page_processor_compatibility) page for mo [//]: # ( @menusnip{altsoftserial} ) -##### NeoSWSerial +##### NeoSWSerial [NeoSWSerial](https://github.com/SRGDamia1/NeoSWSerial) is the best software serial that can be used on any pin supporting interrupts. You can use as many instances of NeoSWSerial as you want. @@ -226,7 +226,7 @@ Not all AVR boards are supported by NeoSWSerial. When using NeoSWSerial we will also have to actually set the data receiving (Rx) pin modes for interrupt in the [setup function](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_setup_serial_interrupts). -##### SoftwareSerial with External Interrupts +##### SoftwareSerial with External Interrupts The "standard" software serial library uses interrupts that conflict with several other libraries used within this program. I've created a [version of software serial that has been stripped of interrupts](https://github.com/EnviroDIY/SoftwareSerial_ExtInts) but it is still far from ideal. @@ -242,7 +242,7 @@ If you only want to use the serial line for incoming or outgoing data, set the o When using SoftwareSerial with External Interrupts we will also have to actually set the data receiving (Rx) pin modes for interrupt in the [setup function](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_setup_serial_interrupts). -##### Software I2C/Wire +##### Software I2C/Wire This creates a software I2C (wire) instance that can be shared between multiple sensors. Only Testato's [SoftwareWire](https://github.com/Testato/SoftwareWire) library is supported. @@ -251,7 +251,7 @@ Only Testato's [SoftwareWire](https://github.com/Testato/SoftwareWire) library i --- -#### SAMD Boards +#### SAMD Boards The SAMD21 supports up to 6 _hardware_ serial ports, which is _awesome_. But, the Arduino core doesn't make use of all of them, so we have to assign them ourselves. @@ -269,7 +269,7 @@ NOTE: The SAMD51 board has an amazing _8_ available SERCOM's, but I do not have --- -### Assigning Serial Port Functionality +### Assigning Serial Port Functionality This section just assigns all the serial ports from the @ref menu_walk_serial_ports section above to specific functionality. For a board with the option of up to 4 hardware serial ports, like the SAMD21 or Arduino Mega, we use the Serial1 to talk to the modem, Serial2 for modbus, and Serial3 for the Maxbotix. @@ -283,7 +283,7 @@ Depending on how you rank the importance of each component, you can adjust these --- -### Logging Options +### Logging Options Here we set options for the logging and dataLogger object. This includes setting the time zone (daylight savings time is **NOT** applied) and setting all of the input and output pins related to the logger. @@ -293,7 +293,7 @@ This includes setting the time zone (daylight savings time is **NOT** applied) a ___ -## Wifi/Cellular Modem Options +## Wifi/Cellular Modem Options This modem section is very lengthy because it contains the code with the constructor for every possible supported modem module. Do _NOT_ try to use more than one modem at a time - it will _NOT_ work. @@ -314,7 +314,7 @@ For WiFi modems, you need the network name and password (assuming WPA2). For cellular models, you will need the APN assigned to you by the carrier you bought your SIM card from. -### Digi XBee Cellular - Transparent Mode +### Digi XBee Cellular - Transparent Mode This is the code to use for _any_ of Digi's cellular XBee or XBee3 modules. All of them can be implented as a DigiXBeeCellularTransparent object - a subclass of DigiXBee and loggerModem. @@ -340,7 +340,7 @@ Setting these helps the modem to connect to network faster. This is shows in the [XBee Cellular Carrier](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_setup_xbeec_carrier) chunk of the setup function. -### Digi XBee3 LTE-M - Bypass Mode +### Digi XBee3 LTE-M - Bypass Mode This code is for Digi's LTE-M XBee3 based on the u-blox SARA R410M - used in bypass mode. To create a DigiXBeeLTEBypass object we need to know @@ -362,7 +362,7 @@ Setting these helps the modem to connect to network faster. This is shows in the [SARA R4 Cellular Carrier](@ref setup_r4_carrrier) chunk of the setup function. -### Digi XBee 3G - Bypass Mode +### Digi XBee 3G - Bypass Mode This code is for Digi's 3G/2G XBee based on the u-blox SARA U201 - used in bypass mode. To create a DigiXBee3GBypass object we need to know @@ -379,7 +379,7 @@ A helpful table detailing the pins to use with the EnviroDIY Mayfly is available [//]: # ( @menusnip{digi_xbee_3g_bypass} ) -### Digi XBee S6B Wifi +### Digi XBee S6B Wifi This code is for the Digi's S6B wifi module. To create a DigiXBeeWifi object we need to know @@ -398,7 +398,7 @@ A helpful table detailing the pins to use with the EnviroDIY Mayfly is available [//]: # ( @menusnip{digi_xbee_wifi} ) -### Espressif ESP8266 +### Espressif ESP8266 This code is for the Espressif ESP8266 or ESP32 operating with "AT" firmware. To create a EspressifESP8266 object we need to know @@ -416,7 +416,7 @@ Because the ESP8266's default baud rate is too fast for an 8MHz board like the M You can set the slower baud rate using some external method, or useing the code from the ESP8266 Baud Rate(https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_setup_esp) part of the setup function below. -### Quectel BG96 +### Quectel BG96 This code is for the Dragino, Nimbelink or other boards based on the Quectel BG96. To create a QuectelBG96 object we need to know @@ -435,7 +435,7 @@ If you are interfacing with a Nimbelink Skywire board via the Skywire developmen Code to invert the pin levels is in the [Skywire Pin Inversions](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_setup_skywire) part of the setup function below. -### Sequans Monarch +### Sequans Monarch This code is for the Nimbelink LTE-M Verizon/Sequans or other boards based on the Sequans Monarch series SoC. To create a SequansMonarch object we need to know @@ -458,7 +458,7 @@ _Before_ attampting to connect a SVZM20 to an Arduino you should connect it to y The proper command to decrease the baud rate to 9600 (8N1) is: `AT+IPR=9600`. -### SIMCom SIM800 +### SIMCom SIM800 This code is for a SIMCom SIM800 or SIM900 or one of their many variants, including the Adafruit Fona and the Sodaq 2GBee R4. To create a SIMComSIM800 object we need to know @@ -477,7 +477,7 @@ See the section for a 2GBee R6. [//]: # ( @menusnip{sim_com_sim800} ) -### SIMCom SIM7000 +### SIMCom SIM7000 This code is for a SIMCom SIM7000 or one of its variants. To create a SIMComSIM7000 object we need to know @@ -493,7 +493,7 @@ Pins that do not apply should be set as -1. [//]: # ( @menusnip{sim_com_sim7000} ) -### SIMCom SIM7080G (EnviroDIY LTE Bee]) +### SIMCom SIM7080G (EnviroDIY LTE Bee]) This code is for a SIMCom SIM7080G or one of its variants, including the [EnviroDIY LTE Bee](https://www.envirodiy.org/product/envirodiy-lte-bee-pack-of-5/). @@ -510,7 +510,7 @@ A helpful table detailing the pins to use with the EnviroDIY LTE Bee and the Env [//]: # ( @menusnip{sim_com_sim7080} ) -### Sodaq GPRSBee +### Sodaq GPRSBee This code is for the Sodaq 2GBee R6 and R7 based on the SIMCom SIM800. To create a Sodaq2GBeeR6 object we need to know @@ -526,7 +526,7 @@ A helpful table detailing the pins to use with the Sodaq GPRSBee and the EnviroD [//]: # ( @menusnip{sodaq_2g_bee_r6} ) -### u-blox SARA R410M +### u-blox SARA R410M This code is for modules based on the 4G LTE-M u-blox SARA R410M including the Sodaq UBee. To create a SodaqUBeeR410M object we need to know @@ -546,7 +546,7 @@ Depending on your cellular carrier, it is best to select the proper carrier prof Setting these helps the modem to connect to network faster. This is shows in the [SARA R4 Cellular Carrier](@ref setup_r4_carrrier) chunk of the setup function. -### u-blox SARA U201 +### u-blox SARA U201 This code is for modules based on the 3G/2G u-blox SARA U201 including the Sodaq UBee or the Sodaq 3GBee. To create a SodaqUBeeU201 object we need to know @@ -562,7 +562,7 @@ A helpful table detailing the pins to use with the Sodaq UBee U201 and the Envir [//]: # ( @menusnip{sodaq_ubee_u201} ) -### Modem Measured Variables +### Modem Measured Variables After creating the modem object, we can create Variable objects for each of the variables the modem is capable of measuring (Modem_SignalPercent, Modem_BatteryState, Modem_BatteryPercent, Modem_BatteryVoltage, and Modem_Temp). When we create the modem-linked variable objects, the first argument of the constructor, the loggerModem to like the variables to is required. @@ -574,9 +574,9 @@ Some modem-measured values may be meaningless depending on the board configurati ___ -## Sensors and Measured Variables +## Sensors and Measured Variables -### The processor as a sensor +### The processor as a sensor Set options and create the objects for using the processor as a sensor to report battery level, processor free ram, and sample number. @@ -592,7 +592,7 @@ The number of "samples" taken will increase by one for each time another process ___ -### Maxim DS3231 RTC as a sensor +### Maxim DS3231 RTC as a sensor In addition to the time, we can also use the required DS3231 real time clock to report the temperature of the circuit board. This temperature is _not_ equivalent to an environmental temperature measurement and should only be used to as a diagnostic. @@ -604,7 +604,7 @@ As above, we create both the sensor and the variables measured by it. ___ -### AOSong AM2315 +### AOSong AM2315 Here is the code for the AOSong AM2315 temperature and humidity sensor. This is an I2C sensor with only one possible address so the only argument required for the constructor is the pin on the MCU controlling power to the AM2315 (AM2315Power). @@ -616,7 +616,7 @@ The number of readings to average from the sensor is optional, but can be suppli ___ -### AOSong DHT +### AOSong DHT Here is the code for the AOSong DHT temperature and humidity sensor. To create the DHT Sensor we need the power pin, the data pin, and the DHT type. @@ -628,7 +628,7 @@ The number of readings to average from the sensor is optional, but can be suppli ___ -### Apogee SQ-212 Quantum Light Sensor +### Apogee SQ-212 Quantum Light Sensor Here is the code for the Apogee SQ-212 Quantum Light Sensor. The SQ-212 is not directly connected to the MCU, but rather to an TI ADS1115 that communicates with the MCU. @@ -643,7 +643,7 @@ The number of readings to average from the sensor is optional, but can be suppli ___ -### Atlas Scientific EZO Circuits +### Atlas Scientific EZO Circuits The next several sections are for Atlas Scientific EZO circuts and sensors. The sensor class constructors for each are nearly identical, except for the class name. @@ -665,7 +665,7 @@ To use multiple circuits of the same type, re-address them. @see @ref atlas_group -#### Atlas Scientific EZO-CO2 Embedded NDIR Carbon Dioxide Sensor +#### Atlas Scientific EZO-CO2 Embedded NDIR Carbon Dioxide Sensor @see @ref sensor_atlas_co2 @@ -674,7 +674,7 @@ To use multiple circuits of the same type, re-address them. ___ -#### Atlas Scientific EZO-DO Dissolved Oxygen Sensor +#### Atlas Scientific EZO-DO Dissolved Oxygen Sensor @see @ref sensor_atlas_do @@ -683,7 +683,7 @@ ___ ___ -#### Atlas Scientific EZO-ORP Oxidation/Reduction Potential Sensor +#### Atlas Scientific EZO-ORP Oxidation/Reduction Potential Sensor @see @ref sensor_atlas_orp @@ -692,7 +692,7 @@ ___ ___ -#### Atlas Scientific EZO-pH Sensor +#### Atlas Scientific EZO-pH Sensor @see @ref sensor_atlas_ph @@ -701,7 +701,7 @@ ___ ___ -#### Atlas Scientific EZO-RTD Temperature Sensor +#### Atlas Scientific EZO-RTD Temperature Sensor @see @ref sensor_atlas_rtd @@ -710,7 +710,7 @@ ___ ___ -#### Atlas Scientific EZO-EC Conductivity Sensor +#### Atlas Scientific EZO-EC Conductivity Sensor @see @ref sensor_atlas_cond @@ -719,7 +719,7 @@ ___ ___ -### Bosch BME280 Environmental Sensor +### Bosch BME280 Environmental Sensor Here is the code for the Bosch BME280 environmental sensor. The only input needed is the Arduino pin controlling power on/off; the i2cAddressHex is optional as is the number of readings to average. @@ -732,7 +732,7 @@ Keep in mind that the possible I2C addresses of the BME280 match those of the MS ___ -### Bosch BMP388 and BMP398 Pressure Sensors +### Bosch BMP388 and BMP398 Pressure Sensors @see @ref sensor_bmp3xx @@ -741,7 +741,7 @@ ___ ___ -#### Campbell ClariVUE SDI-12 Turbidity Sensor +#### Campbell ClariVUE SDI-12 Turbidity Sensor @see @ref sensor_clarivue @@ -750,7 +750,7 @@ ___ ___ -### Campbell OBS3+ Analog Turbidity Sensor +### Campbell OBS3+ Analog Turbidity Sensor This is the code for the Campbell OBS3+. The Arduino pin controlling power on/off, analog data channel _on the TI ADS1115_, and calibration values _in Volts_ for Ax^2 + Bx + C are required for the sensor constructor. @@ -767,7 +767,7 @@ Note that to access both the high and low range returns, two instances must be c ___ -#### Campbell RainVUE SDI-12 Precipitation Sensor +#### Campbell RainVUE SDI-12 Precipitation Sensor @see @ref sensor_rainvue @@ -776,7 +776,7 @@ ___ ___ -#### Decagon CTD-10 Conductivity, Temperature, and Depth Sensor +#### Decagon CTD-10 Conductivity, Temperature, and Depth Sensor @see @ref sensor_decagon_ctd @@ -785,7 +785,7 @@ ___ ___ -### Decagon ES2 Conductivity and Temperature Sensor +### Decagon ES2 Conductivity and Temperature Sensor The SDI-12 address of the sensor, the Arduino pin controlling power on/off, and the Arduino pin sending and receiving data are required for the sensor constructor. Optionally, you can include a number of distinct readings to average. @@ -798,7 +798,7 @@ The data pin must be a pin that supports pin-change interrupts. ___ -#### Everlight ALS-PT19 Ambient Light Sensor +#### Everlight ALS-PT19 Ambient Light Sensor @see @ref sensor_alspt19 @@ -808,7 +808,7 @@ ___ -### External Voltage via TI ADS1x15 +### External Voltage via TI ADS1x15 The Arduino pin controlling power on/off and the analog data channel _on the TI ADS1115_ are required for the sensor constructor. If using a voltage divider to increase the measurable voltage range, enter the gain multiplier as the third argument. @@ -822,7 +822,7 @@ The number of measurements to average, if more than one is desired, goes as the ___ -### Freescale Semiconductor MPL115A2 Miniature I2C Digital Barometer +### Freescale Semiconductor MPL115A2 Miniature I2C Digital Barometer The only input needed for the sensor constructor is the Arduino pin controlling power on/off and optionally the number of readings to average. Because this sensor can have only one I2C address (0x60), it is only possible to connect one of these sensors to your system. @@ -834,7 +834,7 @@ Because this sensor can have only one I2C address (0x60), it is only possible to ___ -### GroPoint Profile GPLP-8 Eight-Segment Soil Moisture and Temperature Profiling Probe +### GroPoint Profile GPLP-8 Eight-Segment Soil Moisture and Temperature Profiling Probe @see @ref sensor_gplp8 @@ -843,7 +843,7 @@ ___ ___ -#### In-Situ Aqua/Level TROLL Pressure, Temperature, and Depth Sensor +#### In-Situ Aqua/Level TROLL Pressure, Temperature, and Depth Sensor @see @ref sensor_insitu_troll @@ -852,7 +852,7 @@ ___ ___ -#### In-Situ RDO PRO-X Rugged Dissolved Oxygen Probe +#### In-Situ RDO PRO-X Rugged Dissolved Oxygen Probe @see @ref sensor_insitu_rdo @@ -861,7 +861,7 @@ ___ ___ -### Keller RS485/Modbus Water Level Sensors +### Keller RS485/Modbus Water Level Sensors The next two sections are for Keller RS485/Modbus water level sensors. The sensor class constructors for each are nearly identical, except for the class name. @@ -882,7 +882,7 @@ Both pins _cannot_ be shared pins. @see @ref keller_group -#### Keller Acculevel High Accuracy Submersible Level Transmitter +#### Keller Acculevel High Accuracy Submersible Level Transmitter @see @ref sensor_acculevel @@ -891,7 +891,7 @@ Both pins _cannot_ be shared pins. ___ -#### Keller Nanolevel Level Transmitter +#### Keller Nanolevel Level Transmitter @see @ref sensor_nanolevel @@ -900,7 +900,7 @@ ___ ___ -### Maxbotix HRXL Ultrasonic Range Finder +### Maxbotix HRXL Ultrasonic Range Finder The Arduino pin controlling power on/off, a stream instance for received data (ie, `Serial`), and the Arduino pin controlling the trigger are required for the sensor constructor. (Use -1 for the trigger pin if you do not have it connected.) @@ -915,7 +915,7 @@ The serial ports for this example are created in the @ref menu_walk_serial_ports ___ -### Maxim DS18 One Wire Temperature Sensor +### Maxim DS18 One Wire Temperature Sensor The OneWire hex address of the sensor, the Arduino pin controlling power on/off, and the Arduino pin sending and receiving data are required for the sensor constructor, though the address can be omitted if only one sensor is used. The OneWire address is an array of 8 hex values, for example: {0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0}. @@ -929,7 +929,7 @@ The sensor address is programmed at the factory and cannot be changed. ___ -### Measurement Specialties MS5803-14BA Pressure Sensor +### Measurement Specialties MS5803-14BA Pressure Sensor The only input needed is the Arduino pin controlling power on/off; the i2cAddressHex and maximum pressure are optional as is the number of readings to average. Keep in mind that the possible I2C addresses of the MS5803 match those of the BME280. @@ -941,7 +941,7 @@ Keep in mind that the possible I2C addresses of the MS5803 match those of the BM ___ -### Meter SDI-12 Sensors +### Meter SDI-12 Sensors The next few sections are for Meter SDI-12 sensors. The SDI-12 address of the sensor, the Arduino pin controlling power on/off, and the Arduino pin sending and receiving data are required for the sensor constructor. @@ -949,7 +949,7 @@ Optionally, you can include a number of distinct readings to average. The data pin must be a pin that supports pin-change interrupts. -#### Meter ECH2O Soil Moisture Sensor +#### Meter ECH2O Soil Moisture Sensor @see @ref sensor_fivetm @@ -958,7 +958,7 @@ The data pin must be a pin that supports pin-change interrupts. ___ -#### Meter Hydros 21 Conductivity, Temperature, and Depth Sensor +#### Meter Hydros 21 Conductivity, Temperature, and Depth Sensor @see @ref sensor_hydros21 @@ -967,7 +967,7 @@ ___ ___ -#### Meter Teros 11 Soil Moisture Sensor +#### Meter Teros 11 Soil Moisture Sensor @see @ref sensor_teros11 @@ -976,7 +976,7 @@ ___ ___ -### PaleoTerra Redox Sensors +### PaleoTerra Redox Sensors Because older versions of these sensors all ship with the same I2C address, and more than one is frequently used at different soil depths in the same profile, this module has an optional dependence on Testato's [SoftwareWire](https://github.com/Testato/SoftwareWire) library for software I2C. @@ -998,7 +998,7 @@ Using some with software I2C and others with hardware I2C is not supported. ___ -### Trinket-Based Tipping Bucket Rain Gauge +### Trinket-Based Tipping Bucket Rain Gauge This is for use with a simple external I2C tipping bucket counter based on the [Adafriut Trinket](https://www.adafruit.com/product/1501). All constructor arguments are optional, but the first argument is for the I2C address of the tip counter (if not 0x08) and the second is for the depth of rain (in mm) per tip event (if not 0.2mm). @@ -1013,7 +1013,7 @@ Note that you cannot input a number of measurements to average because averaging ___ -#### Sensirion SHT4X Digital Humidity and Temperature Sensor +#### Sensirion SHT4X Digital Humidity and Temperature Sensor @see @ref sensor_sht4x @@ -1022,7 +1022,7 @@ ___ ___ -### Northern Widget Tally Event Counter +### Northern Widget Tally Event Counter This is for use with Northern Widget's Tally event counter @@ -1040,7 +1040,7 @@ The counter should be continuously powered. ___ -### TI INA219 High Side Current Sensor +### TI INA219 High Side Current Sensor This is the code for the TI INA219 high side current and voltage sensor. The Arduino pin controlling power on/off is all that is required for the constructor. @@ -1054,7 +1054,7 @@ The number of measurements to average, if more than one is desired, goes as the ___ -### Turner Cyclops-7F Submersible Fluorometer +### Turner Cyclops-7F Submersible Fluorometer This is the code for the Turner Cyclops-7F submersible fluorometer. The Arduino pin controlling power on/off and all calibration information is needed for the constructor. @@ -1071,7 +1071,7 @@ ___ -### Analog Electrical Conductivity using the Processor's Analog Pins +### Analog Electrical Conductivity using the Processor's Analog Pins This is the code for the measuring electrical conductivity using the processor's internal ADC and analog input pins. The Arduino pin controlling power on/off and the sensing pin are required for the constuctor. @@ -1087,7 +1087,7 @@ For best results, you should also connect the AREF pin of your processors ADC to ___ -#### VEGA VEGA PULS 21 +#### VEGA VEGA PULS 21 @see @ref sensor_vega_puls21 @@ -1096,7 +1096,7 @@ ___ ___ -### Yosemitech RS485/Modbus Environmental Sensors +### Yosemitech RS485/Modbus Environmental Sensors The next several sections are for Yosemitech brand sensors. The sensor class constructors for each are nearly identical, except for the class name. @@ -1114,7 +1114,7 @@ The serial ports for this example are created in the @ref menu_walk_serial_ports @see @ref yosemitech_group -#### Yosemitech Y504 Dissolved Oxygen Sensor +#### Yosemitech Y504 Dissolved Oxygen Sensor @see @ref sensor_y504 @@ -1123,7 +1123,7 @@ The serial ports for this example are created in the @ref menu_walk_serial_ports ___ -#### Yosemitech Y510 Turbidity Sensor +#### Yosemitech Y510 Turbidity Sensor @see @ref sensor_y510 @@ -1132,7 +1132,7 @@ ___ ___ -#### Yosemitech Y511 Turbidity Sensor with Wiper +#### Yosemitech Y511 Turbidity Sensor with Wiper @see @ref sensor_y511 @@ -1141,7 +1141,7 @@ ___ ___ -#### Yosemitech Y514 Chlorophyll Sensor +#### Yosemitech Y514 Chlorophyll Sensor @see @ref sensor_y514 @@ -1150,7 +1150,7 @@ ___ ___ -#### Yosemitech Y520 Conductivity Sensor +#### Yosemitech Y520 Conductivity Sensor @see @ref sensor_y520 @@ -1159,7 +1159,7 @@ ___ ___ -#### Yosemitech Y532 pH Sensor +#### Yosemitech Y532 pH Sensor @see @ref sensor_y532 @@ -1168,7 +1168,7 @@ ___ ___ -#### Yosemitech Y533 Oxidation Reduction Potential (ORP) Sensor +#### Yosemitech Y533 Oxidation Reduction Potential (ORP) Sensor @see @ref sensor_y533 @@ -1177,7 +1177,7 @@ ___ ___ -#### Yosemitech Y551 Carbon Oxygen Demand (COD) Sensor with Wiper +#### Yosemitech Y551 Carbon Oxygen Demand (COD) Sensor with Wiper @see @ref sensor_y551 @@ -1186,7 +1186,7 @@ ___ ___ -#### Yosemitech Y560 Ammonium Sensor +#### Yosemitech Y560 Ammonium Sensor @see @ref sensor_y551 @@ -1195,7 +1195,7 @@ ___ ___ -#### Yosemitech Y700 Pressure Sensor +#### Yosemitech Y700 Pressure Sensor @see @ref sensor_y700 @@ -1204,7 +1204,7 @@ ___ ___ -#### Yosemitech Y4000 Multi-Parameter Sonde +#### Yosemitech Y4000 Multi-Parameter Sonde @see @ref sensor_y4000 @@ -1213,7 +1213,7 @@ ___ ___ -### Zebra Tech D-Opto Dissolved Oxygen Sensor +### Zebra Tech D-Opto Dissolved Oxygen Sensor The SDI-12 address of the sensor, the Arduino pin controlling power on/off, and the Arduino pin sending and receiving data are required for the sensor constructor. Optionally, you can include a number of distinct readings to average. @@ -1226,7 +1226,7 @@ The data pin must be a pin that supports pin-change interrupts. ___ -## Calculated Variables +## Calculated Variables Create new Variable objects calculated from the measured variables. For these calculate variables, we must not only supply a function for the calculation, but also all of the metadata about the variable - like the name of the variable and its units. @@ -1235,23 +1235,23 @@ For these calculate variables, we must not only supply a function for the calcul ___ -## Creating the array, logger, publishers +## Creating the array, logger, publishers -### The variable array +### The variable array Create a VariableArray containing all of the Variable objects that we are logging the values of. This shows three differnt ways of creating the same variable array and filling it with variables. You should only use **ONE** of these in your own code -#### Creating Variables within an Array +#### Creating Variables within an Array Here we use the `new` keyword to create multiple variables and get pointers to them all at the same time within the arry. [//]: # ( @menusnip{variables_create_in_array} ) -#### Creating Variables and Pasting UUIDs from MonitorMyWatershed +#### Creating Variables and Pasting UUIDs from MonitorMyWatershed If you are sending data to monitor my watershed, it is much easier to create the variables in an array and then to paste the UUID's all together as copied from the "View Token UUID List" link for a site. If using this method, be very, very, very careful to make sure the order of your variables exactly matches the order of your UUID's. @@ -1259,7 +1259,7 @@ If using this method, be very, very, very careful to make sure the order of your [//]: # ( @menusnip{variables_separate_uuids} ) -#### Creating Variables within an Array +#### Creating Variables within an Array You can also create and name variable pointer objects outside of the array (as is demonstrated in all of the code chunks here) and then reference those pointers inside of the array like so: @@ -1268,7 +1268,7 @@ You can also create and name variable pointer objects outside of the array (as i ___ -### The Logger Object +### The Logger Object Now that we've created the array, we can actually create the #Logger object. @@ -1276,11 +1276,11 @@ Now that we've created the array, we can actually create the #Logger object. ___ -### Data Publishers +### Data Publishers Here we set up all three possible data publisers and link all of them to the same Logger object. -#### Monitor My Watershed +#### Monitor My Watershed To publish data to the Monitor My Watershed / EnviroDIY Data Sharing Portal first you must register yourself as a user at https://monitormywatershed.org or https://data.envirodiy.org. Then you must register your site. @@ -1290,7 +1290,7 @@ After registering your site, a sampling feature and registration token for that ___ -#### DreamHost +#### DreamHost It is extrmemly unlikely you will use this. You should ignore this section. @@ -1299,7 +1299,7 @@ You should ignore this section. ___ -#### ThingSpeak +#### ThingSpeak After you have set up channels on ThingSpeak, you can use this code to publish your data to it. @@ -1309,7 +1309,7 @@ Keep in mind that the order of variables in the VariableArray is **crucial** whe ___ -#### Ubidots +#### Ubidots Use this to publish data to Ubidots. @@ -1317,7 +1317,7 @@ Use this to publish data to Ubidots. ___ -## Extra Working Functions +## Extra Working Functions Here we're creating a few extra functions on the global scope. The flash function is used at board start up just to give an indication that the board has restarted. @@ -1327,7 +1327,7 @@ The battery function calls the #ProcessorStats sensor to check the battery level ___ -## Arduino Setup Function +## Arduino Setup Function This is our setup function. In Arduino coding, the classic "main" function is replaced by two functions: setup() and loop(). @@ -1338,7 +1338,7 @@ Because we have a _lot_ of parts to set up, there's a lot going on in this funct Let's break it down. -### Starting the Function +### Starting the Function First we just open the function definitions: @@ -1346,7 +1346,7 @@ First we just open the function definitions: void setup() { ``` -### Wait for USB +### Wait for USB Next we wait for the USB debugging port to initialize. This only applies to SAMD and 32U4 boards that have built-in USB support. @@ -1354,14 +1354,14 @@ This code should not be used for deployed loggers; it's only for using a USB for [//]: # ( @menusnip{setup_wait} ) -### Printing a Hello +### Printing a Hello Next we print a message out to the debugging port. This is also just for debugging - it's very helpful when connected to the logger via USB to see a clear indication that the board is starting [//]: # ( @menusnip{setup_prints} ) -### Serial Interrupts +### Serial Interrupts If we're using either NeoSWSerial or SoftwareSerial_ExtInts we need to assign the data receiver pins to interrupt functionality here in the setup. @@ -1382,14 +1382,14 @@ For SoftwareSerial with External interrupts we use: [//]: # ( @menusnip{setup_softserial} ) -### Serial Begin +### Serial Begin Every serial port setup and used in the program must be "begun" in the setup function. This section calls the begin functions for all of the various ports defined in the [Extra Serial Ports](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_serial_ports) section [//]: # ( @menusnip{setup_serial_begins} ) -### SAMD Pin Peripherals +### SAMD Pin Peripherals After beginning all of the serial ports, we need to set the pin peripheral settings for any SERCOM's we assigned to serial functionality on the SAMD boards. These were created in the [Extra Serial Ports](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_samd_serial_ports) section above. @@ -1397,14 +1397,14 @@ This does not need to be done for an AVR board (like the Mayfly). [//]: # ( @menusnip{setup_samd_pins} ) -### Flash the LEDs +### Flash the LEDs Like printing debugging information to the serial port, flashing the board LED's is a very helpful indication that the board just restarted. Here we set the pin modes for the LED pins and flash them back and forth using the greenredflash() function we created back in the [working functions](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_working) section. [//]: # ( @menusnip{setup_flashing_led} ) -### Begin the Logger +### Begin the Logger Next get ready and begin the logger. We set the logger time zone and the clock time zone. @@ -1415,7 +1415,7 @@ Then we finally run the logger's begin function. [//]: # ( @menusnip{setup_logger} ) -### Setup the Sensors +### Setup the Sensors After beginning the logger, we setup all the sensors. Unlike all the previous chuncks of the setup that are preparation steps only requiring the mcu processor, this might involve powering up the sensors. @@ -1425,46 +1425,46 @@ Without the condition the board would boot with power, try to power hungry senso [//]: # ( @menusnip{setup_sensors} ) -### Custom Modem Setup +### Custom Modem Setup Next we can opt to do some special setup needed for a few of the modems. You should only use the one chunk that applies to your specific modem configuration and delete the others. -#### ESP8266 Baud Rate +#### ESP8266 Baud Rate This chunk of code reduces the baud rate of the ESP8266 from its default of 115200 to 9600. This is only needed for 8MHz boards (like the Mayfly) that cannot communicate at 115200 baud. [//]: # ( @menusnip{setup_esp} ) -#### Skywire Pin Inversions +#### Skywire Pin Inversions This chunk of code inverts the pin levels for status, wake, and reset of the modem. This is necessary for the Skywire development board and some other breakouts. [//]: # ( @menusnip{setup_skywire} ) -#### SimCom SIM7080G Network Mode +#### SimCom SIM7080G Network Mode This chunk of code sets the network mode and preferred mode for the SIM7080G. [//]: # ( @menusnip{setup_sim7080} ) -#### XBee Cellular Carrier +#### XBee Cellular Carrier This chunk of code sets the carrier profile and network technology for a Digi XBee or XBee3. You should change the lines with the `CP` and `N#` commands to the proper number to match your SIM card. [//]: # ( @menusnip{setup_xbeec_carrier} ) -#### SARA R4 Cellular Carrier +#### SARA R4 Cellular Carrier This chunk of code sets the carrier profile and network technology for a u-blox SARA R4 or N4 module, including a Sodaq R410 UBee or a Digi XBee3 LTE-M in bypass mode.. You should change the lines with the `UMNOPROF` and `URAT` commands to the proper number to match your SIM card. [//]: # ( @menusnip{setup_r4_carrrier} ) -### Sync the Real Time Clock +### Sync the Real Time Clock After any special modem options, we can opt to use the modem to synchronize the real time clock with the NIST time servers. This is very helpful in keeping the clock from drifting or resetting it if it lost time due to power loss. @@ -1476,7 +1476,7 @@ It's a broad range, but it will automatically flag values like Jan 1, 2000 - whi [//]: # ( @menusnip{setup_clock} ) -### Setup File on the SD card +### Setup File on the SD card We're getting close to the end of the setup function! This section verifies that the SD card is communicating with the MCU and sets up a file on it for saved data. @@ -1484,14 +1484,14 @@ Like with the sensors and the modem, we check for battery level before attemptin [//]: # ( @menusnip{setup_file} ) -### Sleep until the First Data Collection Time +### Sleep until the First Data Collection Time We're finally fished with setup! This chunk puts the system into low power deep sleep until the next logging interval. [//]: # ( @menusnip{setup_sleep} ) -### Setup Complete +### Setup Complete Set up is done! This setup function is *really* long. @@ -1503,13 +1503,13 @@ But don't forget you need to close it with a final curly brace. ___ -## Arduino Loop Function +## Arduino Loop Function This is the loop function which will run repeatedly as long as the board is turned on. **NOTE:** This example has code for both a typical simple loop and a complex loop that calls lower level logger functions. You should only pick _one_ loop function and delete the other. -### A Typical Loop +### A Typical Loop After the incredibly long setup function, we can do the vast majority of all logger work in a very simple loop function. Every time the logger wakes we check the battery voltage and do 1 of three things: @@ -1521,7 +1521,7 @@ At full power, do everything. [//]: # ( @menusnip{simple_loop} ) -### A Complex Loop +### A Complex Loop If you need finer control over the steps of the logging function, this code demonstrates how the loop should be constructed. diff --git a/examples/simple_logging_LearnEnviroDIY/ReadMe.md b/examples/simple_logging_LearnEnviroDIY/ReadMe.md index abc46699d..2c78f3612 100644 --- a/examples/simple_logging_LearnEnviroDIY/ReadMe.md +++ b/examples/simple_logging_LearnEnviroDIY/ReadMe.md @@ -1,4 +1,4 @@ -# Learn EnviroDIY Course +# Learn EnviroDIY Course This shows the simplest use of a "logger" object. That is, creating an array of variable objects and then creating a logger object that utilizes those variables to update all of the variable results together and save the data to a SD card. @@ -26,13 +26,13 @@ _______ _______ -# Unique Features of the Learn EnviroDIY Example +# Unique Features of the Learn EnviroDIY Example - Only logs data to an SD card. - Uses a few more sensors than the other simple logging example -# To Use this Example +# To Use this Example -## Prepare and set up PlatformIO +## Prepare and set up PlatformIO - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/simple_logging_LearnEnviroDIY/platformio.ini) file in the examples/simple_logging_LearnEnviroDIY folder on GitHub. - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. @@ -40,7 +40,7 @@ _______ - Open [simple_logging_LearnEnviroDIY.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/simple_logging_LearnEnviroDIY/simple_logging_LearnEnviroDIY.ino) and save it to your computer. Put it into the src directory of your project. - Delete main.cpp in that folder. -## Set the logger ID +## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -48,7 +48,7 @@ _______ const char *LoggerID = "XXXX"; ``` -## Upload! +## Upload! - Test everything at home **before** deploying out in the wild! _______ diff --git a/examples/single_sensor/ReadMe.md b/examples/single_sensor/ReadMe.md index a68d12824..e7fb2a3d5 100644 --- a/examples/single_sensor/ReadMe.md +++ b/examples/single_sensor/ReadMe.md @@ -1,4 +1,4 @@ -# Using a Single Sensor +# Using a Single Sensor This somewhat trivial example show making use of the unified set of commands to print data from a MaxBotix ultrasonic range finder to the serial port. It also shows creating a calculated variable which is the water depth. @@ -20,13 +20,13 @@ _______ _______ -# Unique Features of the Single Sensor Example +# Unique Features of the Single Sensor Example - Only communicates with and collects data from a single sensor. - Does not make use of any VariableArray or logging features. -# To Use this Example +# To Use this Example -## Prepare and set up PlatformIO +## Prepare and set up PlatformIO - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/single_sensor/platformio.ini) file in the examples/single_sensor folder on GitHub. - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. @@ -34,7 +34,7 @@ _______ - Open [single_sensor.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/single_sensor/single_sensor.ino) and save it to your computer. Put it into the src directory of your project. - Delete main.cpp in that folder. -## Upload! +## Upload! - Upload and see what happens _______ diff --git a/src/LoggerBase.h b/src/LoggerBase.h index ed7e2e53e..caf8480a2 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -110,9 +110,9 @@ class Logger { * @param mcuWakePin The pin used to wake the logger from deep sleep - * expected to be attached to an alarm pin of the real-time clock. Use a * value of -1 to prevent the board from sleeping. - * @param inputArray A variableArray object instance providing data to be - * logged. This is NOT an array of variables, but an object of the variable - * array class. + * @param inputArray A pointer to a variableArray object instance providing + * data to be logged. This is NOT an array of variables, but an object of + * the variable array class. */ Logger(const char* loggerID, uint16_t loggingIntervalMinutes, int8_t SDCardSSPin, int8_t mcuWakePin, VariableArray* inputArray); @@ -450,8 +450,8 @@ class Logger { /** * @brief Set the variable array object. * - * @param inputArray A variable array object instance. This is NOT an array - * of variables, but an object of the variable array class. + * @param inputArray A pointer to a variable array object instance. This is + * NOT an array of variables, but an object of the variable array class. */ void setVariableArray(VariableArray* inputArray); From 1192bf1782c42d629d03b305d404d4664e597abb Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 10 Jun 2024 11:57:13 -0400 Subject: [PATCH 069/138] Bump TinyGSM version, change datatype for modem voltage outputs Signed-off-by: Sara Damiano --- .gitignore | 1 + ChangeLog.md | 35 +++++++++++----------- continuous_integration/dependencies.json | 2 +- library.json | 2 +- src/LoggerModem.cpp | 10 +++---- src/LoggerModem.h | 4 +-- src/modems/DigiXBee3GBypass.h | 4 +-- src/modems/DigiXBeeCellularTransparent.h | 4 +-- src/modems/DigiXBeeLTEBypass.h | 4 +-- src/modems/DigiXBeeWifi.cpp | 10 ++++++- src/modems/DigiXBeeWifi.h | 4 +-- src/modems/EspressifESP8266.h | 4 +-- src/modems/LoggerModemMacros.h | 38 ++++++++++++------------ src/modems/QuectelBG96.h | 4 +-- src/modems/SIMComSIM7000.h | 4 +-- src/modems/SIMComSIM7080.h | 4 +-- src/modems/SIMComSIM800.h | 4 +-- src/modems/SequansMonarch.h | 4 +-- src/modems/SodaqUBeeR410M.h | 4 +-- src/modems/SodaqUBeeU201.h | 4 +-- 20 files changed, 79 insertions(+), 71 deletions(-) diff --git a/.gitignore b/.gitignore index 66e0eaf39..7f8b36ead 100644 --- a/.gitignore +++ b/.gitignore @@ -113,3 +113,4 @@ continuous_integration/output_check_component_inclusion.log continuous_integration/platformio_ci_local.ini pioScripts/install_shared_deps.py runDoxygen_archive.bat +generateKeywords.bat diff --git a/ChangeLog.md b/ChangeLog.md index 7d3c3fd4a..c8e474d4b 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Applied markdown lint to markdown files +- Bumped TinyGSM dependency + - Changed datatypes for modem voltage outputs. + ### Added - Added support for caching readings in RAM and sending in batches. @@ -168,7 +172,7 @@ This means having the pull-up resistors on negates the button signal. The pin mode had been set as `INPUT_PULLUP` for the button, backwards for the Mayfly, since [July of 2017](https://github.com/EnviroDIY/ModularSensors/commit/6bafb0fd149589f71ca6f46b761fe72b1f9523a6). By some electrical luck, with the 0.x versions of the Mayfly, the external pull-down on the button pin was strong enough to out-weigh the incorretly activated pull-up resistors and an interrupt was still registered when the button was pressed. With a different pull-down resistor on the Mayfly 1.x, the button no longer registers with the pull-up resistors active. -So, for most of our users with Mayflies, this will be a _**fix**_. +So, for most of our users with Mayflies, this will be a ***fix***. But for anyone using a different board/processor/button configuration that depended on the processor pull-up resistors, this will be a breaking change and they will need to specify the button mode in the `setTestingModePin` or `setLoggerPins` function to return to the previous behavior. - Added a longer warm up time and removed some of the modem set-up to work with the ESP-IDF AT firmware versions >2.0 - Made sure that all example clock synchronization happens at noon instead of midnight. @@ -222,7 +226,7 @@ This is separate from any calculated variables that are created on-the-fly and d In many cases, this is 0 and in most of the other cases the value is informational only. For the SDI-12 sensors, I'm actually using this to make sure I'm getting the number of values expected. - **Sensor:** Added support for [v0.2.0](https://github.com/EnviroDIY/TippingBucketRainCounter/releases) of the [EnviroDIY/TippingBucketRainCounter](https://github.com/EnviroDIY/TippingBucketRainCounter) device firmware, which added capability to count rotations on a reed-switch anemometer and fixed a critical bug that failed to count high rainfall rates. - - For details, see: https://github.com/EnviroDIY/TippingBucketRainCounter/releases/tag/v0.2.0 + - For details, see: *** @@ -262,7 +266,7 @@ Remove support for AOSong DHT ### Removed -- **Breaking:** Temporarily **_REMOVED_** support for AOSong DHT sensor. +- **Breaking:** Temporarily ***REMOVED*** support for AOSong DHT sensor. - Intend to restore this after updating to support newest Adafruit DHT library *** @@ -298,7 +302,7 @@ Fix YosemiTech Y533 ORP sensor outputs ### Fixed -- Modified `YosemitechY533.h` and examples to work with updated ORP `getValues()` function in https://github.com/EnviroDIY/YosemitechModbus released with v0.2.5. +- Modified `YosemitechY533.h` and examples to work with updated ORP `getValues()` function in released with v0.2.5. *** @@ -364,7 +368,7 @@ Gigantic SDI-12 bug ### Fixed -- Fixes an **_EGREGIOUS_** error in the SDI-12 code causing the code to lock up if debugging was off (but always work with it on) +- Fixes an ***EGREGIOUS*** error in the SDI-12 code causing the code to lock up if debugging was off (but always work with it on) - [Issue #346](https://github.com/EnviroDIY/ModularSensors/issues/346) - This was first introduced in [0.27.5](https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.27.5) - Fix GitHub action for pull requests. @@ -473,11 +477,11 @@ Styling & Doxygen Code Documentation ### Added -- **Documentation:** Automated code documentation using [Doxygen](https://www.doxygen.nl/index.html), now available at https://envirodiy.github.io/ModularSensors/ +- **Documentation:** Automated code documentation using [Doxygen](https://www.doxygen.nl/index.html), now available at ### Fixed -- Fixed issue where the Digi XBee LTE-M modem did not wake during normal logging mode to transmit data to the publisher. See https://github.com/EnviroDIY/ModularSensors/pull/309#commitcomment-39786167 +- Fixed issue where the Digi XBee LTE-M modem did not wake during normal logging mode to transmit data to the publisher. See For more details, see [Pull Request #309: The style sheet](https://github.com/EnviroDIY/ModularSensors/pull/309) @@ -553,7 +557,7 @@ Modem Simplification **NOTE: This release is NOT backwards compatible with previous releases.** -- All code must be updated to the current format for modems and time zones to work with this version of the library. +- All code must be updated to the current format for modems and time zones to work with this version of the library. ### Changed @@ -659,8 +663,8 @@ Support for all Atlas Scientific I2C sensors, compiler-safe begin functions - pH - RTD (temperature - Created empty constructors for the logger, publisher, variable array, and variable classes and all of their subclasses. For all classes created a corresponding "begin" function to set internal class object values. - - See note for more details: https://github.com/EnviroDIY/ModularSensors/commit/b1a619ed74bc790743bce35b3a4e78a2d2237b22 - - The order of input arguments for all variable objects has changed. For variable subclasses (ie, variables from sensors), there is no change to the user. __**For calculated variable objects, all code must be updated!**__ Please check the structure in the examples! Older code will compile without error but the variable metadata fields will be incorrectly populated. + - See note for more details: + - The order of input arguments for all variable objects has changed. For variable subclasses (ie, variables from sensors), there is no change to the user. ****For calculated variable objects, all code must be updated!**** Please check the structure in the examples! Older code will compile without error but the variable metadata fields will be incorrectly populated. - Very preliminary support for SD cards with switchable power ### Removed @@ -745,7 +749,7 @@ Major Update! - Improved power management. - Improved stability. -- A huge number of other changes, with most of them are documented here: https://github.com/EnviroDIY/ModularSensors/pull/173 +- A huge number of other changes, with most of them are documented here: *** @@ -761,7 +765,7 @@ NOTE: This **THIS RELEASE DESTROYS BACKWARDS COMPATIBILITY!!** All `.ino` files ### Fixed -- Fixes issue with MaxSonar giving weird readings, due to buffer not being cleared between readings, as described in https://www.envirodiy.org/topic/minor-glitch-reading-maxbotix-mb7389-with-mayfly/ +- Fixes issue with MaxSonar giving weird readings, due to buffer not being cleared between readings, as described in See PR #160 for a full list of improvements and fixes. @@ -807,7 +811,7 @@ Added sensors and fixed timing bugs - Removed the "checkForUpdate()" function. When asking for a value from a variable, you now must explicitly state whether you want the variable to ask its parent sensor for an updated value or not. - By default, it will _not_ ask the parent sensor to update, but only return the last value received or -9999 if a value has never been received. + By default, it will *not* ask the parent sensor to update, but only return the last value received or -9999 if a value has never been received. ### Fixed @@ -945,7 +949,6 @@ Our first release of the modular sensors library to support easily logging data [0.28.5]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.28.5 [0.28.4]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.28.4 [0.28.3]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.28.3 -[0.28.1]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.28.1 [0.28.0]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.28.0 [0.27.8]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.27.8 [0.27.7]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.27.7 @@ -971,10 +974,6 @@ Our first release of the modular sensors library to support easily logging data [0.6.10]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.6.10 [0.6.9]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.6.9 [0.5.4-beta]: https://github.com/EnviroDIY/ModularSensors/releases/tag/0.5.4-beta -[0.3.0-beta]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.3.0-beta -[0.2.5-beta]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.2.5-beta -[0.2.4-beta]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.2.4-beta -[0.2.2-beta]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.2.2-beta [//]: # ( @tableofcontents{XML:1} ) diff --git a/continuous_integration/dependencies.json b/continuous_integration/dependencies.json index 874230ccb..9d1486adc 100644 --- a/continuous_integration/dependencies.json +++ b/continuous_integration/dependencies.json @@ -48,7 +48,7 @@ { "name": "TinyGSM", "owner": "vshymanskyy", - "version": "~0.11.7", + "version": "~0.12.0", "note": "A small Arduino library for GPRS modules.", "authors": ["Volodymyr Shymanskyy", "Sara Damiano"], "frameworks": "arduino", diff --git a/library.json b/library.json index 687ebf63a..d2d748692 100644 --- a/library.json +++ b/library.json @@ -109,7 +109,7 @@ { "name": "TinyGSM", "owner": "vshymanskyy", - "version": "~0.11.7", + "version": "~0.12.0", "note": "A small Arduino library for GPRS modules.", "authors": ["Volodymyr Shymanskyy", "Sara Damiano"], "frameworks": "arduino", diff --git a/src/LoggerModem.cpp b/src/LoggerModem.cpp index 3b3be5cd7..4a215c7a2 100644 --- a/src/LoggerModem.cpp +++ b/src/LoggerModem.cpp @@ -335,11 +335,11 @@ bool loggerModem::updateModemMetadata(void) { loggerModem::_priorModemTemp = -9999; // Initialize variable - int16_t rssi = -9999; - int16_t percent = -9999; - uint8_t state = 99; - int8_t bpercent = -99; - uint16_t volt = 9999; + int16_t rssi = -9999; + int16_t percent = -9999; + int8_t state = 99; + int8_t bpercent = -99; + int16_t volt = 9999; MS_DBG(F("Modem polling settings:"), String(_pollModemMetaData, BIN)); diff --git a/src/LoggerModem.h b/src/LoggerModem.h index a55736dcc..a5eb818cc 100644 --- a/src/LoggerModem.h +++ b/src/LoggerModem.h @@ -601,8 +601,8 @@ class loggerModem { * @return **bool** True indicates that the communication with the modem was * successful and the values referenced by the pointers should be valid. */ - virtual bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) = 0; + virtual bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) = 0; /** * @brief Get the current temperature provided by the modem module. * diff --git a/src/modems/DigiXBee3GBypass.h b/src/modems/DigiXBee3GBypass.h index c9767e34b..e1e6ee4c1 100644 --- a/src/modems/DigiXBee3GBypass.h +++ b/src/modems/DigiXBee3GBypass.h @@ -135,8 +135,8 @@ class DigiXBee3GBypass : public DigiXBee { uint32_t getNISTTime(void) override; bool getModemSignalQuality(int16_t& rssi, int16_t& percent) override; - bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) override; + bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) override; float getModemChipTemperature(void) override; bool modemHardReset(void) override; diff --git a/src/modems/DigiXBeeCellularTransparent.h b/src/modems/DigiXBeeCellularTransparent.h index 602e2f3a3..372aee4b8 100644 --- a/src/modems/DigiXBeeCellularTransparent.h +++ b/src/modems/DigiXBeeCellularTransparent.h @@ -168,8 +168,8 @@ class DigiXBeeCellularTransparent : public DigiXBee { uint32_t getNISTTime(void) override; bool getModemSignalQuality(int16_t& rssi, int16_t& percent) override; - bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) override; + bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) override; float getModemChipTemperature(void) override; bool updateModemMetadata(void) override; diff --git a/src/modems/DigiXBeeLTEBypass.h b/src/modems/DigiXBeeLTEBypass.h index 0f473dce7..6d52228bc 100644 --- a/src/modems/DigiXBeeLTEBypass.h +++ b/src/modems/DigiXBeeLTEBypass.h @@ -149,8 +149,8 @@ class DigiXBeeLTEBypass : public DigiXBee { uint32_t getNISTTime(void) override; bool getModemSignalQuality(int16_t& rssi, int16_t& percent) override; - bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) override; + bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) override; float getModemChipTemperature(void) override; bool modemHardReset(void) override; diff --git a/src/modems/DigiXBeeWifi.cpp b/src/modems/DigiXBeeWifi.cpp index a874915ab..65aaf9249 100644 --- a/src/modems/DigiXBeeWifi.cpp +++ b/src/modems/DigiXBeeWifi.cpp @@ -370,6 +370,9 @@ uint32_t DigiXBeeWifi::getNISTTime(void) { // Try up to 4 NIST IP addresses attempting to get a timestamp from NIST #if !defined NIST_SERVER_RETRYS +/** + * @brief The number of retry attempts when connecting to the NIST server. + */ #define NIST_SERVER_RETRYS 4 #endif // NIST_SERVER_RETRYS @@ -393,8 +396,13 @@ uint32_t DigiXBeeWifi::getNISTTime(void) { // These are is the IP address of time-[a,b,c,d]-wwv.nist.gov // XBee's address lookup falters on time.nist.gov - +/** + * @brief The port hosting the NIST "time" protocol (37) + */ #define TIME_PROTOCOL_PORT 37 +/** + * @brief The length of the NIST IP address (18) + */ #define IP_STR_LEN 18 const char ipAddr[NIST_SERVER_RETRYS][IP_STR_LEN] = { {"132, 163, 97, 1"}, diff --git a/src/modems/DigiXBeeWifi.h b/src/modems/DigiXBeeWifi.h index 9be12dc88..2e29c2742 100644 --- a/src/modems/DigiXBeeWifi.h +++ b/src/modems/DigiXBeeWifi.h @@ -138,8 +138,8 @@ class DigiXBeeWifi : public DigiXBee { uint32_t getNISTTime(void) override; bool getModemSignalQuality(int16_t& rssi, int16_t& percent) override; - bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) override; + bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) override; float getModemChipTemperature(void) override; bool updateModemMetadata(void) override; diff --git a/src/modems/EspressifESP8266.h b/src/modems/EspressifESP8266.h index 30775c230..bfb972d02 100644 --- a/src/modems/EspressifESP8266.h +++ b/src/modems/EspressifESP8266.h @@ -233,8 +233,8 @@ class EspressifESP8266 : public loggerModem { uint32_t getNISTTime(void) override; bool getModemSignalQuality(int16_t& rssi, int16_t& percent) override; - bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) override; + bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) override; float getModemChipTemperature(void) override; #ifdef MS_ESPRESSIFESP8266_DEBUG_DEEP diff --git a/src/modems/LoggerModemMacros.h b/src/modems/LoggerModemMacros.h index 2611ffc08..a93d7a5d1 100644 --- a/src/modems/LoggerModemMacros.h +++ b/src/modems/LoggerModemMacros.h @@ -589,11 +589,11 @@ #ifdef TINY_GSM_MODEM_HAS_BATTERY /** - * @brief Creates a getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - * uint16_t& milliVolts) function for a specific modem subclass. + * @brief Creates a getModemBatteryStats(int8_t& chargeState, int8_t& percent, + * int16_t& milliVolts) function for a specific modem subclass. * * This is a passthrough to the specific modem's getBattStats(uint8_t& - * chargeState, int8_t& percent, uint16_t& milliVolts) for modems where such + * chargeState, int8_t& percent, int16_t& milliVolts) for modems where such * data is available. * * This populates the entered references with -9999s for modems where such data @@ -601,24 +601,24 @@ * * @param specificModem The modem subclass * - * @return The text of a getModemBatteryStats(uint8_t& chargeState, int8_t& - * percent, uint16_t& milliVolts) function specific to a single modem subclass. + * @return The text of a getModemBatteryStats(int8_t& chargeState, int8_t& + * percent, int16_t& milliVolts) function specific to a single modem subclass. * */ #define MS_MODEM_GET_MODEM_BATTERY_DATA(specificModem) \ bool specificModem::getModemBatteryStats( \ - uint8_t& chargeState, int8_t& percent, uint16_t& milliVolts) { \ + int8_t& chargeState, int8_t& percent, int16_t& milliVolts) { \ MS_DBG(F("Getting modem battery data:")); \ return gsmModem.getBattStats(chargeState, percent, milliVolts); \ } #else /** - * @brief Creates a getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - * uint16_t& milliVolts) function for a specific modem subclass. + * @brief Creates a getModemBatteryStats(int8_t& chargeState, int8_t& percent, + * int16_t& milliVolts) function for a specific modem subclass. * * This is a passthrough to the specific modem's getBattStats(uint8_t& - * chargeState, int8_t& percent, uint16_t& milliVolts) for modems where such + * chargeState, int8_t& percent, int16_t& milliVolts) for modems where such * data is available. * * This populates the entered references with -9999s for modems where such data @@ -626,18 +626,18 @@ * * @param specificModem The modem subclass * - * @return The text of a getModemBatteryStats(uint8_t& chargeState, int8_t& - * percent, uint16_t& milliVolts) function specific to a single modem subclass. + * @return The text of a getModemBatteryStats(int8_t& chargeState, int8_t& + * percent, int16_t& milliVolts) function specific to a single modem subclass. * */ -#define MS_MODEM_GET_MODEM_BATTERY_DATA(specificModem) \ - bool specificModem::getModemBatteryStats( \ - uint8_t& chargeState, int8_t& percent, uint16_t& milliVolts) { \ - MS_DBG(F("This modem doesn't return battery information!")); \ - chargeState = 99; \ - percent = -99; \ - milliVolts = 9999; \ - return false; \ +#define MS_MODEM_GET_MODEM_BATTERY_DATA(specificModem) \ + bool specificModem::getModemBatteryStats( \ + int8_t& chargeState, int8_t& percent, int16_t& milliVolts) { \ + MS_DBG(F("This modem doesn't return battery information!")); \ + chargeState = 99; \ + percent = -99; \ + milliVolts = 9999; \ + return false; \ } #endif diff --git a/src/modems/QuectelBG96.h b/src/modems/QuectelBG96.h index 94185ecd4..771bfc795 100644 --- a/src/modems/QuectelBG96.h +++ b/src/modems/QuectelBG96.h @@ -201,8 +201,8 @@ class QuectelBG96 : public loggerModem { uint32_t getNISTTime(void) override; bool getModemSignalQuality(int16_t& rssi, int16_t& percent) override; - bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) override; + bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) override; float getModemChipTemperature(void) override; bool modemHardReset(void) override; diff --git a/src/modems/SIMComSIM7000.h b/src/modems/SIMComSIM7000.h index ad23daa76..8b455ef3b 100644 --- a/src/modems/SIMComSIM7000.h +++ b/src/modems/SIMComSIM7000.h @@ -192,8 +192,8 @@ class SIMComSIM7000 : public loggerModem { uint32_t getNISTTime(void) override; bool getModemSignalQuality(int16_t& rssi, int16_t& percent) override; - bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) override; + bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) override; float getModemChipTemperature(void) override; #ifdef MS_SIMCOMSIM7000_DEBUG_DEEP diff --git a/src/modems/SIMComSIM7080.h b/src/modems/SIMComSIM7080.h index ef0f10e2e..3dd120371 100644 --- a/src/modems/SIMComSIM7080.h +++ b/src/modems/SIMComSIM7080.h @@ -187,8 +187,8 @@ class SIMComSIM7080 : public loggerModem { uint32_t getNISTTime(void) override; bool getModemSignalQuality(int16_t& rssi, int16_t& percent) override; - bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) override; + bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) override; float getModemChipTemperature(void) override; #ifdef MS_SIMCOMSIM7080_DEBUG_DEEP diff --git a/src/modems/SIMComSIM800.h b/src/modems/SIMComSIM800.h index 51ebeb421..d5e97dc07 100644 --- a/src/modems/SIMComSIM800.h +++ b/src/modems/SIMComSIM800.h @@ -194,8 +194,8 @@ class SIMComSIM800 : public loggerModem { uint32_t getNISTTime(void) override; bool getModemSignalQuality(int16_t& rssi, int16_t& percent) override; - bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) override; + bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) override; float getModemChipTemperature(void) override; #ifdef MS_SIMCOMSIM800_DEBUG_DEEP diff --git a/src/modems/SequansMonarch.h b/src/modems/SequansMonarch.h index a1262ef90..8d9f1bc21 100644 --- a/src/modems/SequansMonarch.h +++ b/src/modems/SequansMonarch.h @@ -225,8 +225,8 @@ class SequansMonarch : public loggerModem { uint32_t getNISTTime(void) override; bool getModemSignalQuality(int16_t& rssi, int16_t& percent) override; - bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) override; + bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) override; float getModemChipTemperature(void) override; #ifdef MS_SEQUANSMONARCH_DEBUG_DEEP diff --git a/src/modems/SodaqUBeeR410M.h b/src/modems/SodaqUBeeR410M.h index 103b52747..1a25f37d3 100644 --- a/src/modems/SodaqUBeeR410M.h +++ b/src/modems/SodaqUBeeR410M.h @@ -303,8 +303,8 @@ class SodaqUBeeR410M : public loggerModem { uint32_t getNISTTime(void) override; bool getModemSignalQuality(int16_t& rssi, int16_t& percent) override; - bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) override; + bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) override; float getModemChipTemperature(void) override; bool modemHardReset(void) override; diff --git a/src/modems/SodaqUBeeU201.h b/src/modems/SodaqUBeeU201.h index e71e7eb85..d09067456 100644 --- a/src/modems/SodaqUBeeU201.h +++ b/src/modems/SodaqUBeeU201.h @@ -200,8 +200,8 @@ class SodaqUBeeU201 : public loggerModem { uint32_t getNISTTime(void) override; bool getModemSignalQuality(int16_t& rssi, int16_t& percent) override; - bool getModemBatteryStats(uint8_t& chargeState, int8_t& percent, - uint16_t& milliVolts) override; + bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, + int16_t& milliVolts) override; float getModemChipTemperature(void) override; #ifdef MS_SODAQUBEEU201_DEBUG_DEEP From be74cde8f716d8275585441d6ab5decfde8e6077 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 10 Jun 2024 14:55:30 -0400 Subject: [PATCH 070/138] Remove Az extensions from XBee WiFi Signed-off-by: Sara Damiano --- src/modems/DigiXBeeWifi.cpp | 75 ------------------------------------- src/modems/DigiXBeeWifi.h | 10 ----- 2 files changed, 85 deletions(-) diff --git a/src/modems/DigiXBeeWifi.cpp b/src/modems/DigiXBeeWifi.cpp index 65aaf9249..5981b8a23 100644 --- a/src/modems/DigiXBeeWifi.cpp +++ b/src/modems/DigiXBeeWifi.cpp @@ -594,78 +594,3 @@ bool DigiXBeeWifi::updateModemMetadata(void) { return success; } - - -// Az extensions -void DigiXBeeWifi::setWiFiId(const char* newSsid, bool copyId) { - uint8_t newSsid_sz = strlen(newSsid); - _ssid = newSsid; - if (copyId) { -/* Do size checks, allocate memory for the LoggerID, copy it there - * then set assignment. - */ -#define WIFI_SSID_MAX_sz 32 - if (newSsid_sz > WIFI_SSID_MAX_sz) { - char* WiFiId2 = (char*)newSsid; - PRINTOUT(F("\n\r LoggerModem:setWiFiId too long: Trimmed to "), - newSsid_sz); - WiFiId2[newSsid_sz] = 0; // Trim max size - newSsid_sz = WIFI_SSID_MAX_sz; - } - if (NULL == _ssid_buf) { - _ssid_buf = new char[newSsid_sz + 2]; // Allow for trailing 0 - } else { - PRINTOUT(F("\nLoggerModem::setWiFiId error - expected NULL ptr")); - } - if (NULL == _ssid_buf) { - // Major problem - PRINTOUT(F("\nLoggerModem::setWiFiId error -no buffer "), - _ssid_buf); - } else { - strcpy(_ssid_buf, newSsid); - _ssid = _ssid_buf; - //_ssid2 = _ssid_buf; - } - MS_DBG(F("\nsetWiFiId cp "), _ssid, " sz: ", newSsid_sz); - } -} - -void DigiXBeeWifi::setWiFiPwd(const char* newPwd, bool copyId) { - uint8_t newPwd_sz = strlen(newPwd); - _pwd = newPwd; - - if (copyId) { -/* Do size checks, allocate memory for the LoggerID, copy it there - * then set assignment. - */ -#define WIFI_PWD_MAX_sz 63 // Len 63 printable chars + 0 - if (newPwd_sz > WIFI_PWD_MAX_sz) { - char* pwd2 = (char*)newPwd; - PRINTOUT(F("\n\r LoggerModem:setWiFiPwd too long: Trimmed to "), - newPwd_sz); - pwd2[newPwd_sz] = 0; // Trim max size - newPwd_sz = WIFI_PWD_MAX_sz; - } - if (NULL == _pwd_buf) { - _pwd_buf = new char[newPwd_sz + 2]; // Allow for trailing 0 - } else { - PRINTOUT(F("\nLoggerModem::setWiFiPwd error - expected NULL ptr")); - } - if (NULL == _pwd_buf) { - // Major problem - PRINTOUT(F("\nLoggerModem::setWiFiPwd error -no buffer "), - _pwd_buf); - } else { - strcpy(_pwd_buf, newPwd); - _pwd = _pwd_buf; - } - MS_DEEP_DBG(F("\nsetWiFiPwd cp "), _ssid, " sz: ", newPwd_sz); - } -} - -String DigiXBeeWifi::getWiFiId(void) { - return _ssid; -} -String DigiXBeeWifi::getWiFiPwd(void) { - return _pwd; -} diff --git a/src/modems/DigiXBeeWifi.h b/src/modems/DigiXBeeWifi.h index 2e29c2742..82b7e34ea 100644 --- a/src/modems/DigiXBeeWifi.h +++ b/src/modems/DigiXBeeWifi.h @@ -144,12 +144,6 @@ class DigiXBeeWifi : public DigiXBee { bool updateModemMetadata(void) override; - // Access Management - void setWiFiId(const char* WiFiId, bool copyId = false); - void setWiFiPwd(const char* WiFiPwd, bool copyId = false); - String getWiFiId(void); - String getWiFiPwd(void); - #ifdef MS_DIGIXBEEWIFI_DEBUG_DEEP StreamDebugger _modemATDebugger; #endif @@ -182,10 +176,6 @@ class DigiXBeeWifi : public DigiXBee { const char* _pwd; bool _maintainAssociation; - // Access Management - char* _ssid_buf = NULL; - char* _pwd_buf = NULL; - uint16_t metadata_failure_count = 0; }; /**@}*/ From a0799a7f3507073d3df7602336bc23813985a144 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 11 Jun 2024 13:06:32 -0400 Subject: [PATCH 071/138] Move XBee defines from middle of function to header Signed-off-by: Sara Damiano --- src/modems/DigiXBeeWifi.cpp | 17 +---------------- src/modems/DigiXBeeWifi.h | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/modems/DigiXBeeWifi.cpp b/src/modems/DigiXBeeWifi.cpp index 5981b8a23..224bf6f47 100644 --- a/src/modems/DigiXBeeWifi.cpp +++ b/src/modems/DigiXBeeWifi.cpp @@ -368,14 +368,6 @@ uint32_t DigiXBeeWifi::getNISTTime(void) { gsmClient.stop(); - // Try up to 4 NIST IP addresses attempting to get a timestamp from NIST -#if !defined NIST_SERVER_RETRYS -/** - * @brief The number of retry attempts when connecting to the NIST server. - */ -#define NIST_SERVER_RETRYS 4 -#endif // NIST_SERVER_RETRYS - for (uint8_t i = 0; i < NIST_SERVER_RETRYS; i++) { // Must ensure that we do not ping the daylight servers more than once // every 4 seconds. NIST clearly specifies here that this is a @@ -396,14 +388,7 @@ uint32_t DigiXBeeWifi::getNISTTime(void) { // These are is the IP address of time-[a,b,c,d]-wwv.nist.gov // XBee's address lookup falters on time.nist.gov -/** - * @brief The port hosting the NIST "time" protocol (37) - */ -#define TIME_PROTOCOL_PORT 37 -/** - * @brief The length of the NIST IP address (18) - */ -#define IP_STR_LEN 18 + const char ipAddr[NIST_SERVER_RETRYS][IP_STR_LEN] = { {"132, 163, 97, 1"}, {"132, 163, 97, 2"}, diff --git a/src/modems/DigiXBeeWifi.h b/src/modems/DigiXBeeWifi.h index 82b7e34ea..e06f94f3c 100644 --- a/src/modems/DigiXBeeWifi.h +++ b/src/modems/DigiXBeeWifi.h @@ -86,6 +86,22 @@ */ #define XBEE_RESET_THRESHOLD 4 +// Try up to 4 NIST IP addresses attempting to get a timestamp from NIST +#if !defined NIST_SERVER_RETRYS +/** + * @brief The number of retry attempts when connecting to the NIST server. + */ +#define NIST_SERVER_RETRYS 4 +#endif // NIST_SERVER_RETRYS +/** + * @brief The port hosting the NIST "time" protocol (37) + */ +#define TIME_PROTOCOL_PORT 37 +/** + * @brief The length of the NIST IP address (18) + */ +#define IP_STR_LEN 18 + /** * @brief The class for the [Digi XBee](@ref modem_digi) * [S6B wifi](@ref modem_digi_wifi) module operating in Digi's "transparent" From 3954156b5cff9a5eaa7a8e35b1d5c1e890b23951 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 11 Jun 2024 13:14:25 -0400 Subject: [PATCH 072/138] Update Doxygen, add docs for private members Signed-off-by: Sara Damiano --- .gitignore | 1 + README.md | 74 +- docs/Doxyfile | 305 ++-- docs/DoxygenLayout.xml | 579 +++---- .../m-EnviroDIY+documentation.compiled.css | 1398 +++++++++++------ docs/mcss-Doxyfile | 4 +- pioScripts/generate_compile_commands.py | 16 +- src/LogBuffer.h | 41 +- src/LoggerBase.h | 10 + src/LoggerModem.h | 12 + src/SensorBase.h | 11 +- src/VariableArray.h | 28 +- src/VariableBase.h | 32 +- src/WatchDogs/WatchDogAVR.h | 4 + src/WatchDogs/WatchDogSAMD.h | 7 + src/dataPublisherBase.h | 5 +- src/modems/DigiXBee3GBypass.h | 2 +- src/modems/DigiXBeeCellularTransparent.h | 6 +- src/modems/DigiXBeeLTEBypass.h | 2 +- src/modems/DigiXBeeWifi.h | 16 +- src/modems/EspressifESP8266.h | 12 +- src/modems/LoggerModemMacros.h | 2 + src/modems/QuectelBG96.h | 2 +- src/modems/SIMComSIM7000.h | 2 +- src/modems/SIMComSIM7080.h | 2 +- src/modems/SIMComSIM800.h | 2 +- src/modems/SequansMonarch.h | 2 +- src/modems/Sodaq2GBeeR6.h | 4 + src/modems/SodaqUBeeR410M.h | 2 +- src/modems/SodaqUBeeU201.h | 2 +- src/publishers/DreamHostPublisher.h | 3 + src/publishers/EnviroDIYPublisher.h | 34 +- src/publishers/ThingSpeakPublisher.h | 19 +- src/publishers/UbidotsPublisher.h | 6 + src/sensors/AOSongAM2315.h | 5 +- src/sensors/AOSongDHT.h | 4 +- src/sensors/ApogeeSQ212.h | 6 + src/sensors/CampbellOBS3.h | 14 +- src/sensors/GroPointGPLP8.h | 2 +- src/sensors/GroPointParent.h | 31 +- src/sensors/InSituTrollSdi12a.h | 6 + src/sensors/KellerAcculevel.h | 4 +- src/sensors/KellerNanolevel.h | 4 +- src/sensors/KellerParent.h | 27 +- src/sensors/MaxBotixSonar.h | 14 +- src/sensors/MaximDS18.h | 27 +- src/sensors/ProcessorStats.h | 6 +- src/sensors/SDI12Sensors.h | 8 +- src/sensors/TIADS1x15.h | 10 + src/sensors/TurnerCyclops.h | 77 +- src/sensors/YosemitechParent.h | 27 +- 51 files changed, 1887 insertions(+), 1032 deletions(-) diff --git a/.gitignore b/.gitignore index 7f8b36ead..b6103055d 100644 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,4 @@ continuous_integration/platformio_ci_local.ini pioScripts/install_shared_deps.py runDoxygen_archive.bat generateKeywords.bat +update_path.bat diff --git a/README.md b/README.md index b5146ebb5..da9a9c120 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ If you're new to EnviroDIY, I suggest you check out the [Just Getting Started](h This Arduino library gives environmental sensors a common interface of functions for use with Arduino-compatible dataloggers, such as the EnviroDIY Mayfly. The ModularSensors library is specifically designed to support wireless, solar-powered environmental data logging applications, that is, to: + - Retrieve data from many physical sensors; - Save that data to a SD memory card; - Transmit that data wirelessly to a web server; and @@ -26,6 +27,7 @@ There is extensive documentation available in the [ModularSensors github pages]( [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [ModularSensors](#modularsensors) - [The EnviroDIY ModularSensors Library](#the-envirodiy-modularsensors-library) - [Supported Sensors](#supported-sensors) @@ -48,19 +50,19 @@ For some generalized information about attaching sensors to an Arduino style boa - [AOSong DHT: humidity & temperature](https://envirodiy.github.io/ModularSensors/group__sensor__dht.html) - [Apogee SQ-212: quantum light sensor, via TI ADS1115](https://envirodiy.github.io/ModularSensors/group__sensor__sq212.html) - [Atlas Scientific EZO Sensors](https://envirodiy.github.io/ModularSensors/group__atlas__group.html) - - [EZO-CO2: Carbon Dioxide and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__atlas__co2.html) - - [EZO-DO: Dissolved Oxygen](https://envirodiy.github.io/ModularSensors/group__sensor__atlas__do.html) - - [EZO-EC: Conductivity, Total Dissolved Solids, Salinity, and Specific Gravity](https://envirodiy.github.io/ModularSensors/group__sensor__atlas__cond.html) - - [EZO-ORP: Oxidation/Reduction Potential](https://envirodiy.github.io/ModularSensors/group__sensor__atlas__orp.html) - - [EZO-pH: pH](https://envirodiy.github.io/ModularSensors/group__sensor__atlas__ph.html) - - [EZO-RTD: Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__atlas__rtd.html) + - [EZO-CO2: Carbon Dioxide and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__atlas__co2.html) + - [EZO-DO: Dissolved Oxygen](https://envirodiy.github.io/ModularSensors/group__sensor__atlas__do.html) + - [EZO-EC: Conductivity, Total Dissolved Solids, Salinity, and Specific Gravity](https://envirodiy.github.io/ModularSensors/group__sensor__atlas__cond.html) + - [EZO-ORP: Oxidation/Reduction Potential](https://envirodiy.github.io/ModularSensors/group__sensor__atlas__orp.html) + - [EZO-pH: pH](https://envirodiy.github.io/ModularSensors/group__sensor__atlas__ph.html) + - [EZO-RTD: Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__atlas__rtd.html) - [Bosch BME280: barometric pressure, humidity & temperature](https://envirodiy.github.io/ModularSensors/group__sensor__bme280.html) - [Bosch BMP388 and BMP390: barometric pressure & temperature](https://envirodiy.github.io/ModularSensors/group__sensor__bmp3xx.html) - [Campbell Scientific OBS-3+: turbidity, via TI ADS1115](https://envirodiy.github.io/ModularSensors/group__sensor__obs3.html) - [Campbell Scientific ClariVUE10: turbidity](https://envirodiy.github.io/ModularSensors/group__sensor__clarivue.html) - [Campbell Scientific RainVUE10: precipitation](https://envirodiy.github.io/ModularSensors/group__sensor__rainvue.html) -- [Decagon Devices ES-2: conductivity ](https://envirodiy.github.io/ModularSensors/group__sensor__es2.html) -- [Decagon Devices CTD-10: conductivity, temperature & depth ](https://envirodiy.github.io/ModularSensors/group__sensor__decagon__ctd.html) +- [Decagon Devices ES-2: conductivity](https://envirodiy.github.io/ModularSensors/group__sensor__es2.html) +- [Decagon Devices CTD-10: conductivity, temperature & depth](https://envirodiy.github.io/ModularSensors/group__sensor__decagon__ctd.html) - [Everlight ALS-PT19 Analog Light Sensor (via processor ADC)](https://envirodiy.github.io/ModularSensors/group__sensor__alspt19.html) - [External Arduino I2C Rain Tipping Bucket Counter: rainfall totals](https://envirodiy.github.io/ModularSensors/group__sensor__i2c__rain.html) - [Freescale Semiconductor MPL115A2: barometric pressure and temperature](https://envirodiy.github.io/ModularSensors/group__sensor__mpl115a2.html) @@ -68,14 +70,14 @@ For some generalized information about attaching sensors to an Arduino style boa - [In-Situ RDO PRO-X: dissolved oxygen](https://envirodiy.github.io/ModularSensors/group__sensor__insitu__rdo.html) - [In-Situ SDI-12 TROLLs: pressure, temperature, and depth](https://envirodiy.github.io/ModularSensors/group__sensor__insitu__troll.html) - [Keller Submersible Level Transmitters: pressure and temperature](https://envirodiy.github.io/ModularSensors/group__keller__group.html) - - [Acculevel](https://envirodiy.github.io/ModularSensors/group__sensor__acculevel.html) - - [Nanolevel](https://envirodiy.github.io/ModularSensors/group__sensor__nanolevel.html) + - [Acculevel](https://envirodiy.github.io/ModularSensors/group__sensor__acculevel.html) + - [Nanolevel](https://envirodiy.github.io/ModularSensors/group__sensor__nanolevel.html) - [MaxBotix MaxSonar: water level](https://envirodiy.github.io/ModularSensors/group__sensor__maxbotix.html) - [Maxim DS18: temperature](https://envirodiy.github.io/ModularSensors/group__sensor__ds18.html) - [Measurement Specialties MS5803: pressure and temperature](https://envirodiy.github.io/ModularSensors/group__sensor__ms5803.html) - Meter Environmental Soil Moisture Probes: soil Ea and volumetric water content - - [Meter ECH2O 5TM](https://envirodiy.github.io/ModularSensors/group__sensor__fivetm.html) - - [Meter Teros 11](https://envirodiy.github.io/ModularSensors/group__sensor__teros11.html) + - [Meter ECH2O 5TM](https://envirodiy.github.io/ModularSensors/group__sensor__fivetm.html) + - [Meter Teros 11](https://envirodiy.github.io/ModularSensors/group__sensor__teros11.html) - [Meter Environmental Hydros 21: conductivity, temperature & depth](https://envirodiy.github.io/ModularSensors/group__sensor__hydros21.html) - [Northern Widget Tally Event Counter: number of events](https://envirodiy.github.io/ModularSensors/group__sensor__tally.html) - [PaleoTerra Redox Sensor: redox potential](https://envirodiy.github.io/ModularSensors/group__sensor__pt__redox.html) @@ -85,20 +87,19 @@ For some generalized information about attaching sensors to an Arduino style boa - [Turner Cyclops-7F: various parameters](https://envirodiy.github.io/ModularSensors/group__sensor__cyclops.html) - [Vega Puls 21: radar distance](https://envirodiy.github.io/ModularSensors/group__sensor__vega__puls21.html) - [Yosemitech: water quality sensors](https://envirodiy.github.io/ModularSensors/group__yosemitech__group.html) - - [Y502-A or Y504-A: Optical DO and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y504.html) - - [Y510-B: Optical Turbidity and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y510.html) - - [Y511-A: Optical Turbidity and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y511.html) - - [Y514-A: Optical Chlorophyll and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y514.html) - - [Y520-A: Conductivity and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y520.html) - - [Y532-A: Digital pH and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y532.html) - - [Y533: ORP, and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y533.html) - - [Y551: UV254/COD, Turbidity, and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y551.html) - - [Y560: Ammonium, Temperature, and pH](https://envirodiy.github.io/ModularSensors/group__sensor__y560.html) - - [Y700: Pressure and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y700.html) - - [Y4000 Multiparameter Sonde](https://envirodiy.github.io/ModularSensors/group__sensor__y4000.html) + - [Y502-A or Y504-A: Optical DO and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y504.html) + - [Y510-B: Optical Turbidity and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y510.html) + - [Y511-A: Optical Turbidity and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y511.html) + - [Y514-A: Optical Chlorophyll and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y514.html) + - [Y520-A: Conductivity and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y520.html) + - [Y532-A: Digital pH and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y532.html) + - [Y533: ORP, and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y533.html) + - [Y551: UV254/COD, Turbidity, and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y551.html) + - [Y560: Ammonium, Temperature, and pH](https://envirodiy.github.io/ModularSensors/group__sensor__y560.html) + - [Y700: Pressure and Temperature](https://envirodiy.github.io/ModularSensors/group__sensor__y700.html) + - [Y4000 Multiparameter Sonde](https://envirodiy.github.io/ModularSensors/group__sensor__y4000.html) - [Zebra-Tech D-Opto: dissolved oxygen](https://envirodiy.github.io/ModularSensors/group__sensor__dopto.html) - ## Data Endpoints Within ModularSensors, the "dataPublisher" objects add the functionality to send data to remote web services. @@ -110,17 +111,16 @@ The currently supported services are the [Monitor My Watershed data portal](http [//]: # ( @todo Page on Data Endpoints ) - ## Supported Cellular/Wifi Modules: For information common to all modems and for tables of the proper class, baud rate, and pins to uses, see the [Modem Notes page](https://envirodiy.github.io/ModularSensors/page_modem_notes.html). - [Digi XBee](https://envirodiy.github.io/ModularSensors/group__modem__digi.html) - - Digi XBee® 3 Cellular LTE-M/NB-IoT - - Digi XBee® 3 Cellular LTE Cat 1 (AT&T or Verizon) - - Digi XBee® Cellular 3G - - Digi XBee® Cellular LTE Cat 1 (Verizon) - - Digi XBee® Wi-Fi (S6B) + - Digi XBee® 3 Cellular LTE-M/NB-IoT + - Digi XBee® 3 Cellular LTE Cat 1 (AT&T or Verizon) + - Digi XBee® Cellular 3G + - Digi XBee® Cellular LTE Cat 1 (Verizon) + - Digi XBee® Wi-Fi (S6B) - [ESP8266](https://envirodiy.github.io/ModularSensors/group__modem__esp8266.html) - [QuectelBG96](https://envirodiy.github.io/ModularSensors/group__modem__bg96.html) - [Sequans Monarch](https://envirodiy.github.io/ModularSensors/group__modem__monarch.html) @@ -130,8 +130,8 @@ For information common to all modems and for tables of the proper class, baud ra - u-blox LTE-M R4 and N4 series, including the [Sodaq uBee](https://envirodiy.github.io/ModularSensors/group__modem__ubee__ltem.html) - u-blox 2G, 3G, and 4G, including the [Sodaq 3GBee](https://envirodiy.github.io/ModularSensors/group__modem__ubee__3g.html) - ## Contributing + Open an [issue](https://github.com/EnviroDIY/ModularSensors/issues) to suggest and discuss potential changes/additions. Feel free to open issues about any bugs you find or any sensors you would like to have added. @@ -140,8 +140,8 @@ Please _take time to familiarize yourself with the [terminology, classes and dat This library is built to fully take advantage of Objecting Oriented Programing (OOP) approaches and is larger and more complicated than many Arduino libraries. There is _extensive_ documentation on our [github pages](https://envirodiy.github.io/ModularSensors/index.html) and an _enormous_ number of comments and debugging printouts in the code itself to help you get going. - ## License + Software sketches and code are released under the BSD 3-Clause License -- See [LICENSE.md](https://github.com/EnviroDIY/ModularSensors/blob/master/LICENSE.md) file for details. Documentation is licensed as [Creative Commons Attribution-ShareAlike 4.0](https://creativecommons.org/licenses/by-sa/4.0/) (CC-BY-SA) copyright. @@ -149,17 +149,17 @@ Documentation is licensed as [Creative Commons Attribution-ShareAlike 4.0](https Hardware designs shared are released, unless otherwise indicated, under the [CERN Open Hardware License 1.2](http://www.ohwr.org/licenses/cern-ohl/v1.2) (CERN_OHL). ## Acknowledgments + [EnviroDIY](http://envirodiy.org/)â„¢ is presented by the Stroud Water Research Center, with contributions from a community of enthusiasts sharing do-it-yourself ideas for environmental science and monitoring. [Sara Damiano](https://github.com/SRGDamia1) is the primary developer of the EnviroDIY ModularSensors library, with input from many [other contributors](https://github.com/EnviroDIY/ModularSensors/graphs/contributors). This project has benefited from the support from the following funders: -* William Penn Foundation -* US Environmental Protection Agency (EPA) -* National Science Foundation, awards [EAR-0724971](http://www.nsf.gov/awardsearch/showAward?AWD_ID=0724971), [EAR-1331856](http://www.nsf.gov/awardsearch/showAward?AWD_ID=1331856), [ACI-1339834](http://www.nsf.gov/awardsearch/showAward?AWD_ID=1339834) -* Stroud Water Research Center endowment - +- William Penn Foundation +- US Environmental Protection Agency (EPA) +- National Science Foundation, awards [EAR-0724971](http://www.nsf.gov/awardsearch/showAward?AWD_ID=0724971), [EAR-1331856](http://www.nsf.gov/awardsearch/showAward?AWD_ID=1331856), [ACI-1339834](http://www.nsf.gov/awardsearch/showAward?AWD_ID=1339834) +- Stroud Water Research Center endowment [//]: # ( @m_innerpage{page_getting_started} ) diff --git a/docs/Doxyfile b/docs/Doxyfile index 840f599d3..ee2146abb 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.9.6 +# Doxyfile 1.11.0 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -63,12 +63,18 @@ PROJECT_BRIEF = "An Arduino library to give environmental sensors a com PROJECT_LOGO = ModularSensors_ubuntu_264x55.png +# With the PROJECT_ICON tag one can specify an icon that is included in the tabs +# when the HTML document is shown. Doxygen will copy the logo to the output +# directory. + +PROJECT_ICON = + # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = ../../ModularSensorsDoxygen +OUTPUT_DIRECTORY = ../../ModularSensors_Doxygen # If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 # sub-directories (in 2 levels) under the output directory of each output format @@ -239,7 +245,7 @@ QT_AUTOBRIEF = NO # not recognized any more. # The default value is: NO. -MULTILINE_CPP_IS_BRIEF = NO +MULTILINE_CPP_IS_BRIEF = YES # By default Python docstrings are displayed as preformatted text and doxygen's # special commands cannot be used. By setting PYTHON_DOCSTRING to NO the @@ -375,11 +381,22 @@ MARKDOWN_SUPPORT = YES # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 5. +# Minimum value: 0, maximum value: 99, default value: 6. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 10 +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0 and GITHUB use the lower case version of title +# with any whitespace replaced by '-' and punctuation characters removed. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = GITHUB + # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or @@ -392,8 +409,8 @@ AUTOLINK_SUPPORT = YES # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. +# versus func(std::string) {}). This also makes the inheritance and +# collaboration diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO @@ -405,9 +422,9 @@ BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. +# https://www.riverbankcomputing.com/software) sources only. Doxygen will parse +# them like normal C++ but will assume all classes use public instead of private +# inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO @@ -504,6 +521,14 @@ LOOKUP_CACHE_SIZE = 0 NUM_PROC_THREADS = 1 +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = YES + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -516,19 +541,19 @@ NUM_PROC_THREADS = 1 # normally produced when WARNINGS is set to YES. # The default value is: NO. -EXTRACT_ALL = YES +EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. -EXTRACT_PRIVATE = NO +EXTRACT_PRIVATE = YES # If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual # methods of a class will be included in the documentation. # The default value is: NO. -EXTRACT_PRIV_VIRTUAL = NO +EXTRACT_PRIV_VIRTUAL = YES # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. @@ -540,7 +565,7 @@ EXTRACT_PACKAGE = NO # included in the documentation. # The default value is: NO. -EXTRACT_STATIC = NO +EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, @@ -889,10 +914,17 @@ WARN_IF_UNDOC_ENUM_VAL = YES # a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS # then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but # at the end of the doxygen process doxygen will return with a non-zero status. -# Possible values are: NO, YES and FAIL_ON_WARNINGS. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. # The default value is: NO. -WARN_AS_ERROR = FAIL_ON_WARNINGS +WARN_AS_ERROR = FAIL_ON_WARNINGS_PRINT # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which @@ -951,8 +983,8 @@ INPUT_ENCODING = UTF-8 # character encoding on a per file pattern basis. Doxygen will compare the file # name with each pattern and apply the encoding instead of the default # INPUT_ENCODING) if there is a match. The character encodings are a list of the -# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding -# "INPUT_ENCODING" for further information on supported encodings. +# form: pattern=encoding (like *.php=ISO-8859-1). +# See also: INPUT_ENCODING for further information on supported encodings. INPUT_FILE_ENCODING = @@ -967,12 +999,12 @@ INPUT_FILE_ENCODING = # Note the list of default checked file patterns might differ from the list of # default file extension mappings. # -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, -# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C -# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, -# *.vhdl, *.ucf, *.qsf and *.ice. +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm, +# *.cpp, *.cppm, *.ccm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, +# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.ixx, *.l, *.cs, *.d, +# *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to +# be provided as doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.c \ *.cc \ @@ -1034,9 +1066,6 @@ EXCLUDE_PATTERNS = # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # ANamespace::AClass, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = @@ -1132,7 +1161,7 @@ FILTER_SOURCE_PATTERNS = # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = README.md +USE_MDFILE_AS_MAINPAGE = # The Fortran standard specifies that for fixed formatted Fortran code all # characters from position 72 are to be considered as comment. A common @@ -1157,7 +1186,8 @@ FORTRAN_COMMENT_AFTER = 72 SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. +# multi-line macros, enums or list initialized variables directly into the +# documentation. # The default value is: NO. INLINE_SOURCES = NO @@ -1296,7 +1326,7 @@ IGNORE_PREFIX = # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. -GENERATE_HTML = NO +GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -1385,11 +1415,11 @@ HTML_EXTRA_FILES = # The HTML_COLORSTYLE tag can be used to specify if the generated HTML output # should be rendered with a dark or light theme. -# Possible values are: LIGHT always generate light mode output, DARK always -# generate dark mode output, AUTO_LIGHT automatically set the mode according to -# the user preference, use light mode if no preference is set (the default), -# AUTO_DARK automatically set the mode according to the user preference, use -# dark mode if no preference is set and TOGGLE allow to user to switch between +# Possible values are: LIGHT always generates light mode output, DARK always +# generates dark mode output, AUTO_LIGHT automatically sets the mode according +# to the user preference, uses light mode if no preference is set (the default), +# AUTO_DARK automatically sets the mode according to the user preference, uses +# dark mode if no preference is set and TOGGLE allows a user to switch between # light and dark mode via a button. # The default value is: AUTO_LIGHT. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1426,15 +1456,6 @@ HTML_COLORSTYLE_SAT = 83 HTML_COLORSTYLE_GAMMA = 88 -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = YES - # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that # are dynamically created via JavaScript. If disabled, the navigation index will @@ -1454,6 +1475,33 @@ HTML_DYNAMIC_MENUS = YES HTML_DYNAMIC_SECTIONS = YES +# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be +# dynamically folded and expanded in the generated HTML source code. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_CODE_FOLDING = YES + +# If the HTML_COPY_CLIPBOARD tag is set to YES then doxygen will show an icon in +# the top right corner of code and text fragments that allows the user to copy +# its content to the clipboard. Note this only works if supported by the browser +# and the web page is served via a secure context (see: +# https://www.w3.org/TR/secure-contexts/), i.e. using the https: or file: +# protocol. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COPY_CLIPBOARD = YES + +# Doxygen stores a couple of settings persistently in the browser (via e.g. +# cookies). By default these settings apply to all HTML pages generated by +# doxygen across all projects. The HTML_PROJECT_COOKIE tag can be used to store +# the settings under a project specific key, such that the user preferences will +# be stored separately. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_PROJECT_COOKIE = + # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to @@ -1584,6 +1632,16 @@ BINARY_TOC = NO TOC_EXPAND = NO +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help @@ -1796,7 +1854,7 @@ MATHJAX_VERSION = MathJax_2 # Possible values are: HTML-CSS (which is slower, but has the best # compatibility. This is the name for Mathjax version 2, for MathJax version 3 # this will be translated into chtml), NativeMML (i.e. MathML. Only supported -# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# for MathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This # is the name for Mathjax version 3, for MathJax version 2 this will be # translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. @@ -2072,9 +2130,16 @@ PDF_HYPERLINKS = YES USE_PDFLATEX = YES -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode -# command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. +# The LATEX_BATCHMODE tag signals the behavior of LaTeX in case of an error. +# Possible values are: NO same as ERROR_STOP, YES same as BATCH, BATCH In batch +# mode nothing is printed on the terminal, errors are scrolled as if is +# hit at every error; missing files that TeX tries to input or request from +# keyboard input (\read on a not open input stream) cause the job to abort, +# NON_STOP In nonstop mode the diagnostic message will appear on the terminal, +# but there is no possibility of user interaction just like in batch mode, +# SCROLL In scroll mode, TeX will stop only for missing files to input or if +# keyboard input is necessary and ERROR_STOP In errorstop mode, TeX will stop at +# each error, asking for user intervention. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -2095,14 +2160,6 @@ LATEX_HIDE_INDICES = NO LATEX_BIB_STYLE = plain -# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_TIMESTAMP = NO - # The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) # path from which the emoji images will be read. If a relative path is entered, # it will be relative to the LATEX_OUTPUT directory. If left blank the @@ -2167,6 +2224,14 @@ RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = +# The RTF_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the RTF_OUTPUT output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTRA_FILES = + #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- @@ -2268,13 +2333,39 @@ DOCBOOK_OUTPUT = docbook #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# AutoGen Definitions (see https://autogen.sourceforge.net/) file that captures # the structure of the code including all documentation. Note that this feature # is still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to Sqlite3 output +#--------------------------------------------------------------------------- + +# If the GENERATE_SQLITE3 tag is set to YES doxygen will generate a Sqlite3 +# database with symbols found by doxygen stored in tables. +# The default value is: NO. + +GENERATE_SQLITE3 = NO + +# The SQLITE3_OUTPUT tag is used to specify where the Sqlite3 database will be +# put. If a relative path is entered the value of OUTPUT_DIRECTORY will be put +# in front of it. +# The default directory is: sqlite3. +# This tag requires that the tag GENERATE_SQLITE3 is set to YES. + +SQLITE3_OUTPUT = sqlite3 + +# The SQLITE3_RECREATE_DB tag is set to YES, the existing doxygen_sqlite3.db +# database file will be recreated with each doxygen run. If set to NO, doxygen +# will warn if a database file is already found and not modify it. +# The default value is: YES. +# This tag requires that the tag GENERATE_SQLITE3 is set to YES. + +SQLITE3_RECREATE_DB = YES + #--------------------------------------------------------------------------- # Configuration options related to the Perl module output #--------------------------------------------------------------------------- @@ -2338,7 +2429,7 @@ MACRO_EXPANSION = YES # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -EXPAND_ONLY_PREDEF = YES +EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES, the include files in the # INCLUDE_PATH will be searched if a #include is found. @@ -2469,15 +2560,15 @@ TAGFILES = GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES, all external class will be listed in -# the class index. If set to NO, only the inherited external classes will be -# listed. +# If the ALLEXTERNALS tag is set to YES, all external classes and namespaces +# will be listed in the class and namespace index. If set to NO, only the +# inherited external classes will be listed. # The default value is: NO. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will be +# in the topic index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. @@ -2491,16 +2582,9 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to diagram generator tools #--------------------------------------------------------------------------- -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2509,7 +2593,7 @@ HIDE_UNDOC_RELATIONS = NO # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: -# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO # The default value is: NO. @@ -2562,13 +2646,19 @@ DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" DOT_FONTPATH = -# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a -# graph for each documented class showing the direct and indirect inheritance -# relations. In case HAVE_DOT is set as well dot will be used to draw the graph, -# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set -# to TEXT the direct and indirect inheritance relations will be shown as texts / -# links. -# Possible values are: NO, YES, TEXT and GRAPH. +# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then doxygen will +# generate a graph for each documented class showing the direct and indirect +# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and +# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case +# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the +# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used. +# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance +# relations will be shown as texts / links. Explicit enabling an inheritance +# graph or choosing a different representation for an inheritance graph of a +# specific class, can be accomplished by means of the command \inheritancegraph. +# Disabling an inheritance graph can be accomplished by means of the command +# \hideinheritancegraph. +# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN. # The default value is: YES. CLASS_GRAPH = YES @@ -2576,15 +2666,21 @@ CLASS_GRAPH = YES # If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a # graph for each documented class showing the direct and indirect implementation # dependencies (inheritance, containment, and class references variables) of the -# class with other documented classes. +# class with other documented classes. Explicit enabling a collaboration graph, +# when COLLABORATION_GRAPH is set to NO, can be accomplished by means of the +# command \collaborationgraph. Disabling a collaboration graph can be +# accomplished by means of the command \hidecollaborationgraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. See also the chapter Grouping -# in the manual. +# groups, showing the direct groups dependencies. Explicit enabling a group +# dependency graph, when GROUP_GRAPHS is set to NO, can be accomplished by means +# of the command \groupgraph. Disabling a directory graph can be accomplished by +# means of the command \hidegroupgraph. See also the chapter Grouping in the +# manual. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2626,8 +2722,8 @@ DOT_UML_DETAILS = NO # The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters # to display on a single line. If the actual line length exceeds this threshold -# significantly it will wrapped across multiple lines. Some heuristics are apply -# to avoid ugly line breaks. +# significantly it will be wrapped across multiple lines. Some heuristics are +# applied to avoid ugly line breaks. # Minimum value: 0, maximum value: 1000, default value: 17. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2644,7 +2740,9 @@ TEMPLATE_RELATIONS = YES # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to # YES then doxygen will generate a graph for each documented file showing the # direct and indirect include dependencies of the file with other documented -# files. +# files. Explicit enabling an include graph, when INCLUDE_GRAPH is is set to NO, +# can be accomplished by means of the command \includegraph. Disabling an +# include graph can be accomplished by means of the command \hideincludegraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2653,7 +2751,10 @@ INCLUDE_GRAPH = YES # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then doxygen will generate a graph for each documented file showing # the direct and indirect include dependencies of the file with other documented -# files. +# files. Explicit enabling an included by graph, when INCLUDED_BY_GRAPH is set +# to NO, can be accomplished by means of the command \includedbygraph. Disabling +# an included by graph can be accomplished by means of the command +# \hideincludedbygraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2693,7 +2794,10 @@ GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the # dependencies a directory has on other directories in a graphical way. The # dependency relations are determined by the #include relations between the -# files in the directories. +# files in the directories. Explicit enabling a directory graph, when +# DIRECTORY_GRAPH is set to NO, can be accomplished by means of the command +# \directorygraph. Disabling a directory graph can be accomplished by means of +# the command \hidedirectorygraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2709,7 +2813,7 @@ DIR_GRAPH_MAX_DEPTH = 5 # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: -# http://www.graphviz.org/)). +# https://www.graphviz.org/)). # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). @@ -2719,7 +2823,7 @@ DIR_GRAPH_MAX_DEPTH = 5 # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_IMAGE_FORMAT = png +DOT_IMAGE_FORMAT = svg # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. @@ -2746,11 +2850,12 @@ DOT_PATH = DOTFILE_DIRS = -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. -MSCFILE_DIRS = +DIA_PATH = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile @@ -2779,7 +2884,7 @@ PLANTUML_INCLUDE_PATH = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes # larger than this value, doxygen will truncate the graph, which is visualized -# by representing a node as a red box. Note that doxygen if the number of direct +# by representing a node as a red box. Note that if the number of direct # children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that # the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. @@ -2827,3 +2932,19 @@ GENERATE_LEGEND = YES # The default value is: YES. DOT_CLEANUP = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. If the MSCGEN_TOOL tag is left empty (the default), then doxygen will +# use a built-in version of mscgen tool to produce the charts. Alternatively, +# the MSCGEN_TOOL tag can also specify the name an external tool. For instance, +# specifying prog as the value, doxygen will call the tool as prog -T +# -o . The external tool should support +# output file formats "png", "eps", "svg", and "ismap". + +MSCGEN_TOOL = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = diff --git a/docs/DoxygenLayout.xml b/docs/DoxygenLayout.xml index 9dc8a05a6..834b7f1a6 100644 --- a/docs/DoxygenLayout.xml +++ b/docs/DoxygenLayout.xml @@ -1,328 +1,269 @@ + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + diff --git a/docs/css/m-EnviroDIY+documentation.compiled.css b/docs/css/m-EnviroDIY+documentation.compiled.css index ce5c1158e..7b457fc2e 100644 --- a/docs/css/m-EnviroDIY+documentation.compiled.css +++ b/docs/css/m-EnviroDIY+documentation.compiled.css @@ -3,7 +3,7 @@ /* This file is part of m.css. - Copyright © 2017, 2018, 2019, 2020, 2021, 2022 + Copyright © 2017, 2018, 2019, 2020, 2021, 2022, 2023 Vladimír VondruÅ¡ Permission is hereby granted, free of charge, to any person obtaining a @@ -25,8 +25,14 @@ DEALINGS IN THE SOFTWARE. */ -*, ::before, ::after { box-sizing: border-box; } -body { margin: 0; } +*, +::before, +::after { + box-sizing: border-box; +} +body { + margin: 0; +} .m-container { width: 100%; margin: auto; @@ -54,83 +60,172 @@ body { margin: 0; } [class*='m-show-'] { display: none; } -.m-container-inflate, :not(.m-row) > [class*='m-col-'] { +.m-container-inflate, +:not(.m-row) > [class*='m-col-'] { margin-bottom: 1rem; } -.m-container-inflate:last-child, :not(.m-row) > [class*='m-col-']:last-child { +.m-container-inflate:last-child, +:not(.m-row) > [class*='m-col-']:last-child { margin-bottom: 0; } -.m-container.m-nopad, [class*='m-col-'].m-nopad, -.m-container.m-nopadx, [class*='m-col-'].m-nopadx, -.m-container.m-nopadl, [class*='m-col-'].m-nopadl { +.m-container.m-nopad, +[class*='m-col-'].m-nopad, +.m-container.m-nopadx, +[class*='m-col-'].m-nopadx, +.m-container.m-nopadl, +[class*='m-col-'].m-nopadl { padding-left: 0; } -.m-container.m-nopad, [class*='m-col-'].m-nopad, -.m-container.m-nopadx, [class*='m-col-'].m-nopadx, -.m-container.m-nopadr, [class*='m-col-'].m-nopadr { +.m-container.m-nopad, +[class*='m-col-'].m-nopad, +.m-container.m-nopadx, +[class*='m-col-'].m-nopadx, +.m-container.m-nopadr, +[class*='m-col-'].m-nopadr { padding-right: 0; } -[class*='m-col-'].m-nopad, [class*='m-col-'].m-nopady, [class*='m-col-'].m-nopadt { +[class*='m-col-'].m-nopad, +[class*='m-col-'].m-nopady, +[class*='m-col-'].m-nopadt { padding-top: 0; } -[class*='m-col-'].m-nopad, [class*='m-col-'].m-nopady, [class*='m-col-'].m-nopadb, +[class*='m-col-'].m-nopad, +[class*='m-col-'].m-nopady, +[class*='m-col-'].m-nopadb, .m-container-inflate.m-nopadb { padding-bottom: 0; } -[class*='m-col-t-'] { float: left; } +[class*='m-col-t-'] { + float: left; +} .m-left-t { padding-right: 1rem; float: left; } -.m-right-t, [class*='m-col-t-'].m-right-t { +.m-right-t, +[class*='m-col-t-'].m-right-t { padding-left: 1rem; float: right; } -.m-center-t, [class*='m-col-t-'].m-center-t { +.m-center-t, +[class*='m-col-t-'].m-center-t { float: none; } -.m-center-t, [class*='m-col-t-'].m-center-t { +.m-center-t, +[class*='m-col-t-'].m-center-t { margin-left: auto; margin-right: auto; float: none; } -.m-col-t-1 { width: calc(1 * 100% / 12); } -.m-col-t-2 { width: calc(2 * 100% / 12); } -.m-col-t-3 { width: calc(3 * 100% / 12); } -.m-col-t-4 { width: calc(4 * 100% / 12); } -.m-col-t-5 { width: calc(5 * 100% / 12); } -.m-col-t-6 { width: calc(6 * 100% / 12); } -.m-col-t-7 { width: calc(7 * 100% / 12); } -.m-col-t-8 { width: calc(8 * 100% / 12); } -.m-col-t-9 { width: calc(9 * 100% / 12); } -.m-col-t-10 { width: calc(10 * 100% / 12); } -.m-col-t-11 { width: calc(11 * 100% / 12); } -.m-col-t-12 { width: calc(12 * 100% / 12); } -.m-push-t-1 { left: calc(1 * 100% / 12); } -.m-push-t-2 { left: calc(2 * 100% / 12); } -.m-push-t-3 { left: calc(3 * 100% / 12); } -.m-push-t-4 { left: calc(4 * 100% / 12); } -.m-push-t-5 { left: calc(5 * 100% / 12); } -.m-push-t-6 { left: calc(6 * 100% / 12); } -.m-push-t-7 { left: calc(7 * 100% / 12); } -.m-push-t-8 { left: calc(8 * 100% / 12); } -.m-push-t-9 { left: calc(9 * 100% / 12); } -.m-push-t-10 { left: calc(10 * 100% / 12); } -.m-push-t-11 { left: calc(11 * 100% / 12); } -.m-pull-t-1 { right: calc(1 * 100% / 12); } -.m-pull-t-2 { right: calc(2 * 100% / 12); } -.m-pull-t-3 { right: calc(3 * 100% / 12); } -.m-pull-t-4 { right: calc(4 * 100% / 12); } -.m-pull-t-5 { right: calc(5 * 100% / 12); } -.m-pull-t-6 { right: calc(6 * 100% / 12); } -.m-pull-t-7 { right: calc(7 * 100% / 12); } -.m-pull-t-8 { right: calc(8 * 100% / 12); } -.m-pull-t-9 { right: calc(9 * 100% / 12); } -.m-pull-t-10 { right: calc(10 * 100% / 12); } -.m-pull-t-11 { right: calc(11 * 100% / 12); } +.m-col-t-1 { + width: calc(1 * 100% / 12); +} +.m-col-t-2 { + width: calc(2 * 100% / 12); +} +.m-col-t-3 { + width: calc(3 * 100% / 12); +} +.m-col-t-4 { + width: calc(4 * 100% / 12); +} +.m-col-t-5 { + width: calc(5 * 100% / 12); +} +.m-col-t-6 { + width: calc(6 * 100% / 12); +} +.m-col-t-7 { + width: calc(7 * 100% / 12); +} +.m-col-t-8 { + width: calc(8 * 100% / 12); +} +.m-col-t-9 { + width: calc(9 * 100% / 12); +} +.m-col-t-10 { + width: calc(10 * 100% / 12); +} +.m-col-t-11 { + width: calc(11 * 100% / 12); +} +.m-col-t-12 { + width: calc(12 * 100% / 12); +} +.m-push-t-1 { + left: calc(1 * 100% / 12); +} +.m-push-t-2 { + left: calc(2 * 100% / 12); +} +.m-push-t-3 { + left: calc(3 * 100% / 12); +} +.m-push-t-4 { + left: calc(4 * 100% / 12); +} +.m-push-t-5 { + left: calc(5 * 100% / 12); +} +.m-push-t-6 { + left: calc(6 * 100% / 12); +} +.m-push-t-7 { + left: calc(7 * 100% / 12); +} +.m-push-t-8 { + left: calc(8 * 100% / 12); +} +.m-push-t-9 { + left: calc(9 * 100% / 12); +} +.m-push-t-10 { + left: calc(10 * 100% / 12); +} +.m-push-t-11 { + left: calc(11 * 100% / 12); +} +.m-pull-t-1 { + right: calc(1 * 100% / 12); +} +.m-pull-t-2 { + right: calc(2 * 100% / 12); +} +.m-pull-t-3 { + right: calc(3 * 100% / 12); +} +.m-pull-t-4 { + right: calc(4 * 100% / 12); +} +.m-pull-t-5 { + right: calc(5 * 100% / 12); +} +.m-pull-t-6 { + right: calc(6 * 100% / 12); +} +.m-pull-t-7 { + right: calc(7 * 100% / 12); +} +.m-pull-t-8 { + right: calc(8 * 100% / 12); +} +.m-pull-t-9 { + right: calc(9 * 100% / 12); +} +.m-pull-t-10 { + right: calc(10 * 100% / 12); +} +.m-pull-t-11 { + right: calc(11 * 100% / 12); +} @media screen and (min-width: 576px) { - .m-container { width: 560px; } - .m-container-inflatable .m-col-s-10 .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { + .m-container { + width: 560px; + } + .m-container-inflatable + .m-col-s-10 + .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { margin-left: -10%; margin-right: -10%; } @@ -140,67 +235,153 @@ body { margin: 0; } .m-container-inflatable .m-col-s-10 .m-container-inflate.m-right-s { margin-right: -10%; } - [class*='m-col-s-'] { float: left; } + [class*='m-col-s-'] { + float: left; + } .m-left-s { padding-right: 1rem; float: left; } - .m-right-s, [class*='m-col-s-'].m-right-s { + .m-right-s, + [class*='m-col-s-'].m-right-s { padding-left: 1rem; float: right; } - .m-center-s, [class*='m-col-s-'].m-center-s { + .m-center-s, + [class*='m-col-s-'].m-center-s { margin-left: auto; margin-right: auto; float: none; } - .m-col-s-1 { width: calc(1 * 100% / 12); } - .m-col-s-2 { width: calc(2 * 100% / 12); } - .m-col-s-3 { width: calc(3 * 100% / 12); } - .m-col-s-4 { width: calc(4 * 100% / 12); } - .m-col-s-5 { width: calc(5 * 100% / 12); } - .m-col-s-6 { width: calc(6 * 100% / 12); } - .m-col-s-7 { width: calc(7 * 100% / 12); } - .m-col-s-8 { width: calc(8 * 100% / 12); } - .m-col-s-9 { width: calc(9 * 100% / 12); } - .m-col-s-10 { width: calc(10 * 100% / 12); } - .m-col-s-11 { width: calc(11 * 100% / 12); } - .m-col-s-12 { width: calc(12 * 100% / 12); } - .m-push-s-0 { left: calc(0 * 100% / 12); } - .m-push-s-1 { left: calc(1 * 100% / 12); } - .m-push-s-2 { left: calc(2 * 100% / 12); } - .m-push-s-3 { left: calc(3 * 100% / 12); } - .m-push-s-4 { left: calc(4 * 100% / 12); } - .m-push-s-5 { left: calc(5 * 100% / 12); } - .m-push-s-6 { left: calc(6 * 100% / 12); } - .m-push-s-7 { left: calc(7 * 100% / 12); } - .m-push-s-8 { left: calc(8 * 100% / 12); } - .m-push-s-9 { left: calc(9 * 100% / 12); } - .m-push-s-10 { left: calc(10 * 100% / 12); } - .m-push-s-11 { left: calc(11 * 100% / 12); } - .m-pull-s-0 { right: calc(0 * 100% / 12); } - .m-pull-s-1 { right: calc(1 * 100% / 12); } - .m-pull-s-2 { right: calc(2 * 100% / 12); } - .m-pull-s-3 { right: calc(3 * 100% / 12); } - .m-pull-s-4 { right: calc(4 * 100% / 12); } - .m-pull-s-5 { right: calc(5 * 100% / 12); } - .m-pull-s-6 { right: calc(6 * 100% / 12); } - .m-pull-s-7 { right: calc(7 * 100% / 12); } - .m-pull-s-8 { right: calc(8 * 100% / 12); } - .m-pull-s-9 { right: calc(9 * 100% / 12); } - .m-pull-s-10 { right: calc(10 * 100% / 12); } - .m-pull-s-11 { right: calc(11 * 100% / 12); } - .m-clearfix-t::after { display: none; } - .m-hide-s { display: none; } - .m-show-s { display: block; } + .m-col-s-1 { + width: calc(1 * 100% / 12); + } + .m-col-s-2 { + width: calc(2 * 100% / 12); + } + .m-col-s-3 { + width: calc(3 * 100% / 12); + } + .m-col-s-4 { + width: calc(4 * 100% / 12); + } + .m-col-s-5 { + width: calc(5 * 100% / 12); + } + .m-col-s-6 { + width: calc(6 * 100% / 12); + } + .m-col-s-7 { + width: calc(7 * 100% / 12); + } + .m-col-s-8 { + width: calc(8 * 100% / 12); + } + .m-col-s-9 { + width: calc(9 * 100% / 12); + } + .m-col-s-10 { + width: calc(10 * 100% / 12); + } + .m-col-s-11 { + width: calc(11 * 100% / 12); + } + .m-col-s-12 { + width: calc(12 * 100% / 12); + } + .m-push-s-0 { + left: calc(0 * 100% / 12); + } + .m-push-s-1 { + left: calc(1 * 100% / 12); + } + .m-push-s-2 { + left: calc(2 * 100% / 12); + } + .m-push-s-3 { + left: calc(3 * 100% / 12); + } + .m-push-s-4 { + left: calc(4 * 100% / 12); + } + .m-push-s-5 { + left: calc(5 * 100% / 12); + } + .m-push-s-6 { + left: calc(6 * 100% / 12); + } + .m-push-s-7 { + left: calc(7 * 100% / 12); + } + .m-push-s-8 { + left: calc(8 * 100% / 12); + } + .m-push-s-9 { + left: calc(9 * 100% / 12); + } + .m-push-s-10 { + left: calc(10 * 100% / 12); + } + .m-push-s-11 { + left: calc(11 * 100% / 12); + } + .m-pull-s-0 { + right: calc(0 * 100% / 12); + } + .m-pull-s-1 { + right: calc(1 * 100% / 12); + } + .m-pull-s-2 { + right: calc(2 * 100% / 12); + } + .m-pull-s-3 { + right: calc(3 * 100% / 12); + } + .m-pull-s-4 { + right: calc(4 * 100% / 12); + } + .m-pull-s-5 { + right: calc(5 * 100% / 12); + } + .m-pull-s-6 { + right: calc(6 * 100% / 12); + } + .m-pull-s-7 { + right: calc(7 * 100% / 12); + } + .m-pull-s-8 { + right: calc(8 * 100% / 12); + } + .m-pull-s-9 { + right: calc(9 * 100% / 12); + } + .m-pull-s-10 { + right: calc(10 * 100% / 12); + } + .m-pull-s-11 { + right: calc(11 * 100% / 12); + } + .m-clearfix-t::after { + display: none; + } + .m-hide-s { + display: none; + } + .m-show-s { + display: block; + } .m-col-s-none { width: auto; float: none; } } @media screen and (min-width: 768px) { - .m-container { width: 750px; } - .m-container-inflatable .m-col-m-10 .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { + .m-container { + width: 750px; + } + .m-container-inflatable + .m-col-m-10 + .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { margin-left: -10%; margin-right: -10%; } @@ -210,67 +391,153 @@ body { margin: 0; } .m-container-inflatable .m-col-m-10 .m-container-inflate.m-right-m { margin-right: -10%; } - [class*='m-col-m-'] { float: left; } + [class*='m-col-m-'] { + float: left; + } .m-left-m { padding-right: 1rem; float: left; } - .m-right-m, [class*='m-col-m-'].m-right-m { + .m-right-m, + [class*='m-col-m-'].m-right-m { padding-left: 1rem; float: right; } - .m-center-m, [class*='m-col-m-'].m-center-m { + .m-center-m, + [class*='m-col-m-'].m-center-m { margin-left: auto; margin-right: auto; float: none; } - .m-col-m-1 { width: calc(1 * 100% / 12); } - .m-col-m-2 { width: calc(2 * 100% / 12); } - .m-col-m-3 { width: calc(3 * 100% / 12); } - .m-col-m-4 { width: calc(4 * 100% / 12); } - .m-col-m-5 { width: calc(5 * 100% / 12); } - .m-col-m-6 { width: calc(6 * 100% / 12); } - .m-col-m-7 { width: calc(7 * 100% / 12); } - .m-col-m-8 { width: calc(8 * 100% / 12); } - .m-col-m-9 { width: calc(9 * 100% / 12); } - .m-col-m-10 { width: calc(10 * 100% / 12); } - .m-col-m-11 { width: calc(11 * 100% / 12); } - .m-col-m-12 { width: calc(12 * 100% / 12); } - .m-push-m-0 { left: calc(0 * 100% / 12); } - .m-push-m-1 { left: calc(1 * 100% / 12); } - .m-push-m-2 { left: calc(2 * 100% / 12); } - .m-push-m-3 { left: calc(3 * 100% / 12); } - .m-push-m-4 { left: calc(4 * 100% / 12); } - .m-push-m-5 { left: calc(5 * 100% / 12); } - .m-push-m-6 { left: calc(6 * 100% / 12); } - .m-push-m-7 { left: calc(7 * 100% / 12); } - .m-push-m-8 { left: calc(8 * 100% / 12); } - .m-push-m-9 { left: calc(9 * 100% / 12); } - .m-push-m-10 { left: calc(10 * 100% / 12); } - .m-push-m-11 { left: calc(11 * 100% / 12); } - .m-pull-m-0 { right: calc(0 * 100% / 12); } - .m-pull-m-1 { right: calc(1 * 100% / 12); } - .m-pull-m-2 { right: calc(2 * 100% / 12); } - .m-pull-m-3 { right: calc(3 * 100% / 12); } - .m-pull-m-4 { right: calc(4 * 100% / 12); } - .m-pull-m-5 { right: calc(5 * 100% / 12); } - .m-pull-m-6 { right: calc(6 * 100% / 12); } - .m-pull-m-7 { right: calc(7 * 100% / 12); } - .m-pull-m-8 { right: calc(8 * 100% / 12); } - .m-pull-m-9 { right: calc(9 * 100% / 12); } - .m-pull-m-10 { right: calc(10 * 100% / 12); } - .m-pull-m-11 { right: calc(11 * 100% / 12); } - .m-clearfix-s::after { display: none; } - .m-hide-m { display: none; } - .m-show-m { display: block; } + .m-col-m-1 { + width: calc(1 * 100% / 12); + } + .m-col-m-2 { + width: calc(2 * 100% / 12); + } + .m-col-m-3 { + width: calc(3 * 100% / 12); + } + .m-col-m-4 { + width: calc(4 * 100% / 12); + } + .m-col-m-5 { + width: calc(5 * 100% / 12); + } + .m-col-m-6 { + width: calc(6 * 100% / 12); + } + .m-col-m-7 { + width: calc(7 * 100% / 12); + } + .m-col-m-8 { + width: calc(8 * 100% / 12); + } + .m-col-m-9 { + width: calc(9 * 100% / 12); + } + .m-col-m-10 { + width: calc(10 * 100% / 12); + } + .m-col-m-11 { + width: calc(11 * 100% / 12); + } + .m-col-m-12 { + width: calc(12 * 100% / 12); + } + .m-push-m-0 { + left: calc(0 * 100% / 12); + } + .m-push-m-1 { + left: calc(1 * 100% / 12); + } + .m-push-m-2 { + left: calc(2 * 100% / 12); + } + .m-push-m-3 { + left: calc(3 * 100% / 12); + } + .m-push-m-4 { + left: calc(4 * 100% / 12); + } + .m-push-m-5 { + left: calc(5 * 100% / 12); + } + .m-push-m-6 { + left: calc(6 * 100% / 12); + } + .m-push-m-7 { + left: calc(7 * 100% / 12); + } + .m-push-m-8 { + left: calc(8 * 100% / 12); + } + .m-push-m-9 { + left: calc(9 * 100% / 12); + } + .m-push-m-10 { + left: calc(10 * 100% / 12); + } + .m-push-m-11 { + left: calc(11 * 100% / 12); + } + .m-pull-m-0 { + right: calc(0 * 100% / 12); + } + .m-pull-m-1 { + right: calc(1 * 100% / 12); + } + .m-pull-m-2 { + right: calc(2 * 100% / 12); + } + .m-pull-m-3 { + right: calc(3 * 100% / 12); + } + .m-pull-m-4 { + right: calc(4 * 100% / 12); + } + .m-pull-m-5 { + right: calc(5 * 100% / 12); + } + .m-pull-m-6 { + right: calc(6 * 100% / 12); + } + .m-pull-m-7 { + right: calc(7 * 100% / 12); + } + .m-pull-m-8 { + right: calc(8 * 100% / 12); + } + .m-pull-m-9 { + right: calc(9 * 100% / 12); + } + .m-pull-m-10 { + right: calc(10 * 100% / 12); + } + .m-pull-m-11 { + right: calc(11 * 100% / 12); + } + .m-clearfix-s::after { + display: none; + } + .m-hide-m { + display: none; + } + .m-show-m { + display: block; + } .m-col-m-none { width: auto; float: none; } } @media screen and (min-width: 992px) { - .m-container { width: 960px; } - .m-container-inflatable .m-col-l-10 .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { + .m-container { + width: 960px; + } + .m-container-inflatable + .m-col-l-10 + .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { margin-left: -10%; margin-right: -10%; } @@ -280,59 +547,141 @@ body { margin: 0; } .m-container-inflatable .m-col-l-10 .m-container-inflate.m-right-l { margin-right: -10%; } - [class*='m-col-l-'] { float: left; } + [class*='m-col-l-'] { + float: left; + } .m-left-l { padding-right: 1rem; float: left; } - .m-right-l, [class*='m-col-l-'].m-right-l { + .m-right-l, + [class*='m-col-l-'].m-right-l { padding-left: 1rem; float: right; } - .m-center-l, [class*='m-col-l-'].m-center-l { + .m-center-l, + [class*='m-col-l-'].m-center-l { margin-left: auto; margin-right: auto; float: none; } - .m-col-l-1 { width: calc(1 * 100% / 12); } - .m-col-l-2 { width: calc(2 * 100% / 12); } - .m-col-l-3 { width: calc(3 * 100% / 12); } - .m-col-l-4 { width: calc(4 * 100% / 12); } - .m-col-l-5 { width: calc(5 * 100% / 12); } - .m-col-l-6 { width: calc(6 * 100% / 12); } - .m-col-l-7 { width: calc(7 * 100% / 12); } - .m-col-l-8 { width: calc(8 * 100% / 12); } - .m-col-l-9 { width: calc(9 * 100% / 12); } - .m-col-l-10 { width: calc(10 * 100% / 12); } - .m-col-l-11 { width: calc(11 * 100% / 12); } - .m-col-l-12 { width: calc(12 * 100% / 12); } - .m-push-l-0 { left: calc(0 * 100% / 12); } - .m-push-l-1 { left: calc(1 * 100% / 12); } - .m-push-l-2 { left: calc(2 * 100% / 12); } - .m-push-l-3 { left: calc(3 * 100% / 12); } - .m-push-l-4 { left: calc(4 * 100% / 12); } - .m-push-l-5 { left: calc(5 * 100% / 12); } - .m-push-l-6 { left: calc(6 * 100% / 12); } - .m-push-l-7 { left: calc(7 * 100% / 12); } - .m-push-l-8 { left: calc(8 * 100% / 12); } - .m-push-l-9 { left: calc(9 * 100% / 12); } - .m-push-l-10 { left: calc(10 * 100% / 12); } - .m-push-l-11 { left: calc(11 * 100% / 12); } - .m-pull-l-0 { right: calc(0 * 100% / 12); } - .m-pull-l-1 { right: calc(1 * 100% / 12); } - .m-pull-l-2 { right: calc(2 * 100% / 12); } - .m-pull-l-3 { right: calc(3 * 100% / 12); } - .m-pull-l-4 { right: calc(4 * 100% / 12); } - .m-pull-l-5 { right: calc(5 * 100% / 12); } - .m-pull-l-6 { right: calc(6 * 100% / 12); } - .m-pull-l-7 { right: calc(7 * 100% / 12); } - .m-pull-l-8 { right: calc(8 * 100% / 12); } - .m-pull-l-9 { right: calc(9 * 100% / 12); } - .m-pull-l-10 { right: calc(10 * 100% / 12); } - .m-pull-l-11 { right: calc(11 * 100% / 12); } - .m-clearfix-m::after { display: none; } - .m-hide-l { display: none; } - .m-show-l { display: block; } + .m-col-l-1 { + width: calc(1 * 100% / 12); + } + .m-col-l-2 { + width: calc(2 * 100% / 12); + } + .m-col-l-3 { + width: calc(3 * 100% / 12); + } + .m-col-l-4 { + width: calc(4 * 100% / 12); + } + .m-col-l-5 { + width: calc(5 * 100% / 12); + } + .m-col-l-6 { + width: calc(6 * 100% / 12); + } + .m-col-l-7 { + width: calc(7 * 100% / 12); + } + .m-col-l-8 { + width: calc(8 * 100% / 12); + } + .m-col-l-9 { + width: calc(9 * 100% / 12); + } + .m-col-l-10 { + width: calc(10 * 100% / 12); + } + .m-col-l-11 { + width: calc(11 * 100% / 12); + } + .m-col-l-12 { + width: calc(12 * 100% / 12); + } + .m-push-l-0 { + left: calc(0 * 100% / 12); + } + .m-push-l-1 { + left: calc(1 * 100% / 12); + } + .m-push-l-2 { + left: calc(2 * 100% / 12); + } + .m-push-l-3 { + left: calc(3 * 100% / 12); + } + .m-push-l-4 { + left: calc(4 * 100% / 12); + } + .m-push-l-5 { + left: calc(5 * 100% / 12); + } + .m-push-l-6 { + left: calc(6 * 100% / 12); + } + .m-push-l-7 { + left: calc(7 * 100% / 12); + } + .m-push-l-8 { + left: calc(8 * 100% / 12); + } + .m-push-l-9 { + left: calc(9 * 100% / 12); + } + .m-push-l-10 { + left: calc(10 * 100% / 12); + } + .m-push-l-11 { + left: calc(11 * 100% / 12); + } + .m-pull-l-0 { + right: calc(0 * 100% / 12); + } + .m-pull-l-1 { + right: calc(1 * 100% / 12); + } + .m-pull-l-2 { + right: calc(2 * 100% / 12); + } + .m-pull-l-3 { + right: calc(3 * 100% / 12); + } + .m-pull-l-4 { + right: calc(4 * 100% / 12); + } + .m-pull-l-5 { + right: calc(5 * 100% / 12); + } + .m-pull-l-6 { + right: calc(6 * 100% / 12); + } + .m-pull-l-7 { + right: calc(7 * 100% / 12); + } + .m-pull-l-8 { + right: calc(8 * 100% / 12); + } + .m-pull-l-9 { + right: calc(9 * 100% / 12); + } + .m-pull-l-10 { + right: calc(10 * 100% / 12); + } + .m-pull-l-11 { + right: calc(11 * 100% / 12); + } + .m-clearfix-m::after { + display: none; + } + .m-hide-l { + display: none; + } + .m-show-l { + display: block; + } .m-col-l-none { width: auto; float: none; @@ -565,21 +914,21 @@ ol.m-unstyled { list-style-type: none; padding-left: 0; } -ul[class*="m-block-"], -ol[class*="m-block-"] { +ul[class*='m-block-'], +ol[class*='m-block-'] { padding-left: 0; } -ul[class*="m-block-"] li, -ol[class*="m-block-"] li { +ul[class*='m-block-'] li, +ol[class*='m-block-'] li { display: inline; } -ul[class*="m-block-bar-"] li:not(:last-child)::after, -ol[class*="m-block-bar-"] li:not(:last-child)::after { - content: " | "; +ul[class*='m-block-bar-'] li:not(:last-child)::after, +ol[class*='m-block-bar-'] li:not(:last-child)::after { + content: ' | '; } -ul[class*="m-block-dot-"] li:not(:last-child)::after, -ol[class*="m-block-dot-"] li:not(:last-child)::after { - content: " • "; +ul[class*='m-block-dot-'] li:not(:last-child)::after, +ol[class*='m-block-dot-'] li:not(:last-child)::after { + content: ' • '; } @media screen and (min-width: 576px) { ul.m-block-bar-s, @@ -598,7 +947,7 @@ ol[class*="m-block-dot-"] li:not(:last-child)::after { ol.m-block-bar-s li:not(:last-child)::after, ul.m-block-dot-s li:not(:last-child)::after, ol.m-block-dot-s li:not(:last-child)::after { - content: ""; + content: ''; } } @media screen and (min-width: 768px) { @@ -618,7 +967,7 @@ ol[class*="m-block-dot-"] li:not(:last-child)::after { ol.m-block-bar-m li:not(:last-child)::after, ul.m-block-dot-m li:not(:last-child)::after, ol.m-block-dot-m li:not(:last-child)::after { - content: ""; + content: ''; } } @media screen and (min-width: 992px) { @@ -638,7 +987,7 @@ ol[class*="m-block-dot-"] li:not(:last-child)::after { ol.m-block-bar-l li:not(:last-child)::after, ul.m-block-dot-l li:not(:last-child)::after, ol.m-block-dot-l li:not(:last-child)::after { - content: ""; + content: ''; } } p.m-poem { @@ -683,10 +1032,10 @@ dl.m-footnote dd span.m-footnote a { text-decoration: none; } a.m-footnote::before { - content: "["; + content: '['; } a.m-footnote::after { - content: "]"; + content: ']'; } dl.m-footnote dt { width: 1.5rem; @@ -741,7 +1090,7 @@ dl.m-footnote dd span.m-footnote a { border-color: #92d050; } .m-block.m-badge::after { - content: " "; + content: ' '; display: block; clear: both; } @@ -891,7 +1240,9 @@ table.m-table th.m-info, table.m-table td.m-dim, table.m-table th.m-dim, table.m-table td.m-param, -table.m-table th.m-param { +table.m-table th.m-param, +table.m-table td.m-type, +table.m-table th.m-type { padding-left: 0.4375rem; padding-right: 0.4375rem; } @@ -910,7 +1261,9 @@ table.m-table.m-big th.m-info, table.m-table.m-big td.m-dim, table.m-table.m-big th.m-dim, table.m-table.m-big td.m-param, -table.m-table.m-big th.m-param { +table.m-table.m-big th.m-param, +table.m-table.m-big td.m-type, +table.m-table.m-big th.m-type { padding-left: 0.9375rem; padding-right: 0.9375rem; } @@ -945,7 +1298,11 @@ table.m-table th.m-dim, table.m-table tr.m-param td, table.m-table td.m-param, table.m-table tr.m-param th, -table.m-table th.m-param { +table.m-table th.m-param, +table.m-table tr.m-type td, +table.m-table td.m-type, +table.m-table tr.m-type th, +table.m-table th.m-type { border-color: #e8e8e8; } .m-note pre, @@ -997,11 +1354,18 @@ table.m-table tr.m-param code, table.m-table td.m-param pre, table.m-table td.m-param code, table.m-table th.m-param pre, -table.m-table th.m-param code { +table.m-table th.m-param code, +table.m-table tr.m-type pre, +table.m-table tr.m-type code, +table.m-table td.m-type pre, +table.m-table td.m-type code, +table.m-table th.m-type pre, +table.m-table th.m-type code { background-color: rgba(251, 240, 236, 0.5); } img.m-image, -svg.m-image { +svg.m-image, +video.m-image { display: block; margin-left: auto; margin-right: auto; @@ -1011,13 +1375,16 @@ div.m-image { } img.m-image, svg.m-image, +video.m-image, div.m-image img, -div.m-image svg { +div.m-image svg, +div.m-image video { max-width: 100%; border-radius: 0px; } div.m-image.m-fullwidth img, -div.m-image.m-fullwidth svg { +div.m-image.m-fullwidth svg, +div.m-image.m-fullwidth video { width: 100%; } img.m-image.m-badge, @@ -1034,7 +1401,7 @@ figure.m-figure { } figure.m-figure::before { position: absolute; - content: " "; + content: ' '; top: 0; bottom: 0; left: 0; @@ -1061,7 +1428,8 @@ figure.m-figure > *:last-child { margin-bottom: 1rem !important; } figure.m-figure img, -figure.m-figure svg { +figure.m-figure svg, +figure.m-figure video { position: relative; margin-left: 0; margin-right: 0; @@ -1071,12 +1439,14 @@ figure.m-figure svg { max-width: 100%; } figure.m-figure.m-flat img, -figure.m-figure.m-flat svg { +figure.m-figure.m-flat svg, +figure.m-figure.m-flat video { border-bottom-left-radius: 0px; border-bottom-right-radius: 0px; } figure.m-figure a img, -figure.m-figure a svg { +figure.m-figure a svg, +figure.m-figure a video { margin-left: -1rem; margin-right: -1rem; } @@ -1088,11 +1458,12 @@ figure.m-figure.m-fullwidth > *:first-child { display: inline; } figure.m-figure.m-fullwidth img, -figure.m-figure.m-fullwidth svg { +figure.m-figure.m-fullwidth svg, +figure.m-figure.m-fullwidth video { width: 100%; } figure.m-figure.m-fullwidth::after { - content: " "; + content: ' '; display: block; margin-top: 1rem; height: 1px; @@ -1108,7 +1479,7 @@ figure.m-figure.m-fullwidth::after { .m-code-figure::before, .m-console-figure::before { position: absolute; - content: " "; + content: ' '; top: 0; bottom: 0; left: 0; @@ -1211,7 +1582,7 @@ figure.m-figure figcaption .m-figure-description a { .m-imagegrid > div > figure > figcaption::before, .m-imagegrid > div > figure > a > div::before, .m-imagegrid > div > figure > a > figcaption::before { - content: ""; + content: ''; display: inline-block; height: 100%; vertical-align: bottom; @@ -1233,7 +1604,7 @@ figure.m-figure figcaption .m-figure-description a { } .m-imagegrid > div::after { display: block; - content: " "; + content: ' '; clear: both; } @media screen and (max-width: 767px) { @@ -1249,41 +1620,41 @@ figure.m-figure figcaption .m-figure-description a { border-right-width: 0; } } -.m-container-inflatable > .m-row > [class*="m-col-"] > .m-note, -.m-container-inflatable > .m-row > [class*="m-col-"] > .m-frame, -.m-container-inflatable > .m-row > [class*="m-col-"] > .m-block, -.m-container-inflatable > .m-row > [class*="m-col-"] > .m-imagegrid, -.m-container-inflatable > .m-row > [class*="m-col-"] > pre, -.m-container-inflatable > .m-row > [class*="m-col-"] > .m-code-figure, -.m-container-inflatable > .m-row > [class*="m-col-"] > .m-console-figure, -.m-container-inflatable > .m-row > [class*="m-col-"] section > .m-note, -.m-container-inflatable > .m-row > [class*="m-col-"] section > .m-frame, -.m-container-inflatable > .m-row > [class*="m-col-"] section > .m-block, -.m-container-inflatable > .m-row > [class*="m-col-"] section > .m-imagegrid, -.m-container-inflatable > .m-row > [class*="m-col-"] section > pre, -.m-container-inflatable > .m-row > [class*="m-col-"] section > .m-code-figure, -.m-container-inflatable > .m-row > [class*="m-col-"] section > .m-console-figure, -.m-container-inflatable [class*="m-center-"] > .m-note, -.m-container-inflatable [class*="m-center-"] > .m-frame, -.m-container-inflatable [class*="m-center-"] > .m-block, -.m-container-inflatable [class*="m-center-"] > .m-imagegrid, -.m-container-inflatable [class*="m-center-"] > pre, -.m-container-inflatable [class*="m-center-"] > .m-code-figure, -.m-container-inflatable [class*="m-center-"] > .m-console-figure, -.m-container-inflatable [class*="m-left-"] > .m-note, -.m-container-inflatable [class*="m-left-"] > .m-frame, -.m-container-inflatable [class*="m-left-"] > .m-block, -.m-container-inflatable [class*="m-left-"] > .m-imagegrid, -.m-container-inflatable [class*="m-left-"] > pre, -.m-container-inflatable [class*="m-left-"] > .m-code-figure, -.m-container-inflatable [class*="m-left-"] > .m-console-figure, -.m-container-inflatable [class*="m-right-"] > .m-note, -.m-container-inflatable [class*="m-right-"] > .m-frame, -.m-container-inflatable [class*="m-right-"] > .m-block, -.m-container-inflatable [class*="m-right-"] > .m-imagegrid, -.m-container-inflatable [class*="m-right-"] > pre, -.m-container-inflatable [class*="m-right-"] > .m-code-figure, -.m-container-inflatable [class*="m-right-"] > .m-console-figure, +.m-container-inflatable > .m-row > [class*='m-col-'] > .m-note, +.m-container-inflatable > .m-row > [class*='m-col-'] > .m-frame, +.m-container-inflatable > .m-row > [class*='m-col-'] > .m-block, +.m-container-inflatable > .m-row > [class*='m-col-'] > .m-imagegrid, +.m-container-inflatable > .m-row > [class*='m-col-'] > pre, +.m-container-inflatable > .m-row > [class*='m-col-'] > .m-code-figure, +.m-container-inflatable > .m-row > [class*='m-col-'] > .m-console-figure, +.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-note, +.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-frame, +.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-block, +.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-imagegrid, +.m-container-inflatable > .m-row > [class*='m-col-'] section > pre, +.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-code-figure, +.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-console-figure, +.m-container-inflatable [class*='m-center-'] > .m-note, +.m-container-inflatable [class*='m-center-'] > .m-frame, +.m-container-inflatable [class*='m-center-'] > .m-block, +.m-container-inflatable [class*='m-center-'] > .m-imagegrid, +.m-container-inflatable [class*='m-center-'] > pre, +.m-container-inflatable [class*='m-center-'] > .m-code-figure, +.m-container-inflatable [class*='m-center-'] > .m-console-figure, +.m-container-inflatable [class*='m-left-'] > .m-note, +.m-container-inflatable [class*='m-left-'] > .m-frame, +.m-container-inflatable [class*='m-left-'] > .m-block, +.m-container-inflatable [class*='m-left-'] > .m-imagegrid, +.m-container-inflatable [class*='m-left-'] > pre, +.m-container-inflatable [class*='m-left-'] > .m-code-figure, +.m-container-inflatable [class*='m-left-'] > .m-console-figure, +.m-container-inflatable [class*='m-right-'] > .m-note, +.m-container-inflatable [class*='m-right-'] > .m-frame, +.m-container-inflatable [class*='m-right-'] > .m-block, +.m-container-inflatable [class*='m-right-'] > .m-imagegrid, +.m-container-inflatable [class*='m-right-'] > pre, +.m-container-inflatable [class*='m-right-'] > .m-code-figure, +.m-container-inflatable [class*='m-right-'] > .m-console-figure, .m-container-inflatable .m-container-inflate > .m-note, .m-container-inflatable .m-container-inflate > .m-frame, .m-container-inflatable .m-container-inflate > .m-block, @@ -1325,10 +1696,7 @@ figure.m-figure figcaption .m-figure-description a { margin-left: 0; margin-right: -1rem; } - .m-container-inflatable - > .m-row - > .m-col-s-10 - > .m-imagegrid.m-container-inflate, + .m-container-inflatable > .m-row > .m-col-s-10 > .m-imagegrid.m-container-inflate, .m-container-inflatable > .m-row > .m-col-s-10 @@ -1369,10 +1737,7 @@ figure.m-figure figcaption .m-figure-description a { margin-left: 0; margin-right: -1rem; } - .m-container-inflatable - > .m-row - > .m-col-m-10 - > .m-imagegrid.m-container-inflate, + .m-container-inflatable > .m-row > .m-col-m-10 > .m-imagegrid.m-container-inflate, .m-container-inflatable > .m-row > .m-col-m-10 @@ -1413,10 +1778,7 @@ figure.m-figure figcaption .m-figure-description a { margin-left: 0; margin-right: -1rem; } - .m-container-inflatable - > .m-row - > .m-col-l-10 - > .m-imagegrid.m-container-inflate, + .m-container-inflatable > .m-row > .m-col-l-10 > .m-imagegrid.m-container-inflate, .m-container-inflatable > .m-row > .m-col-l-10 @@ -1893,6 +2255,20 @@ span.m-dim a:active { .m-block.m-param h6 a:active { color: #9ad36a; } +.m-block.m-type h3 a:hover, +.m-block.m-type h3 a:focus, +.m-block.m-type h3 a:active, +.m-block.m-type h4 a:hover, +.m-block.m-type h4 a:focus, +.m-block.m-type h4 a:active, +.m-block.m-type h5 a:hover, +.m-block.m-type h5 a:focus, +.m-block.m-type h5 a:active, +.m-block.m-type h6 a:hover, +.m-block.m-type h6 a:focus, +.m-block.m-type h6 a:active { + color: var(--type-link-active-color); +} div.m-button a, .m-label { color: #ffffff; @@ -1933,18 +2309,23 @@ div.m-button.m-danger a, div.m-button.m-info a, .m-label:not(.m-flat).m-info { background-color: #31708f; - color: #81bcda; + color: #5dc1ed; } div.m-button.m-dim a, .m-label:not(.m-flat).m-dim { background-color: #666; - color: #7c7c7c; + color: #9e9d9d; } div.m-button.m-param a, .m-label:not(.m-flat).m-param { background-color: #9ad36a; color: #3c763d; } +div.m-button.m-type a, +.m-label:not(.m-flat).m-type { + background-color: var(--type-color); + color: var(--type-filled-color); +} div.m-button.m-default a:hover, div.m-button.m-default a:focus, div.m-button.m-default a:active { @@ -1985,6 +2366,11 @@ div.m-button.m-param a:focus, div.m-button.m-param a:active { background-color: #9ad36a; } +div.m-button.m-type a:hover, +div.m-button.m-type a:focus, +div.m-button.m-type a:active { + background-color: var(--type-link-active-color); +} .m-note.m-default { background-color: transparent; border-width: 2px; @@ -2210,7 +2596,7 @@ table.m-table strong.m-info, table.m-table tr.m-info em, table.m-table em.m-info { background-color: transparent; - color: #81bcda; + color: #5dc1ed; } .m-note.m-info a, table.m-table tr.m-info td a, @@ -2252,7 +2638,7 @@ table.m-table strong.m-dim, table.m-table tr.m-dim em, table.m-table em.m-dim { background-color: transparent; - color: #7c7c7c; + color: #9e9d9d; } .m-note.m-dim a, table.m-table tr.m-dim td a, @@ -2320,6 +2706,38 @@ table.m-table tr.m-param th a:active, table.m-table th.m-param a:active { color: #9ad36a; } +.m-note.m-type, +table.m-table tr.m-type td, +table.m-table td.m-type, +table.m-table tr.m-type th, +table.m-table th.m-type { + background-color: var(--type-filled-background-color); + color: var(--type-filled-color); +} +.m-note.m-type a, +table.m-table tr.m-type td a, +table.m-table td.m-type a, +table.m-table tr.m-type th a, +table.m-table th.m-type a { + color: var(--type-filled-link-color); +} +.m-note.m-type a:hover, +table.m-table tr.m-type td a:hover, +table.m-table td.m-type a:hover, +table.m-table tr.m-type th a:hover, +table.m-table th.m-type a:hover, +.m-note.m-type a:focus, +table.m-table tr.m-type td a:focus, +table.m-table td.m-type a:focus, +table.m-table tr.m-type th a:focus, +table.m-table th.m-type a:focus, +.m-note.m-type a:active, +table.m-table tr.m-type td a:active, +table.m-table td.m-type a:active, +table.m-table tr.m-type th a:active, +table.m-table th.m-type a:active { + color: var(--type-filled-link-active-color); +} figure.m-figure.m-default::before { border-color: transparent; } @@ -2377,6 +2795,12 @@ figure.m-figure.m-param::before { figure.m-figure.m-param figcaption { color: #9ad36a; } +figure.m-figure.m-type::before { + border-color: var(--type-filled-background-color); +} +figure.m-figure.m-type figcaption { + color: var(--type-color); +} figure.m-figure.m-dim::before { border-color: transparent; } @@ -2564,6 +2988,24 @@ div.m-plot svg .m-bar.m-param, .m-graph.m-param g.m-node polyline { stroke: #9ad36a; } +.m-math.m-type, +.m-math g.m-type, +.m-math rect.m-type, +div.m-plot svg .m-bar.m-type, +.m-graph.m-type g.m-edge polygon, +.m-graph.m-type g.m-node:not(.m-flat) ellipse, +.m-graph.m-type g.m-node:not(.m-flat) polygon, +.m-graph.m-type g.m-edge text, +.m-graph.m-type g.m-node.m-flat text { + fill: var(--type-color); +} +.m-graph.m-type g.m-edge polygon, +.m-graph.m-type g.m-edge path, +.m-graph.m-type g.m-node ellipse, +.m-graph.m-type g.m-node polygon, +.m-graph.m-type g.m-node polyline { + stroke: var(--type-color); +} .m-graph g.m-edge.m-default polygon, .m-graph g.m-node.m-default:not(.m-flat) ellipse, .m-graph g.m-node.m-default:not(.m-flat) polygon, @@ -2691,6 +3133,21 @@ div.m-plot svg .m-bar.m-param, .m-graph g.m-cluster.m-param polygon { stroke: #9ad36a; } +.m-graph g.m-edge.m-type polygon, +.m-graph g.m-node.m-type:not(.m-flat) ellipse, +.m-graph g.m-node.m-type:not(.m-flat) polygon, +.m-graph g.m-edge.m-type text, +.m-graph g.m-node.m-type.m-flat text { + fill: var(--type-color); +} +.m-graph g.m-edge.m-type polygon, +.m-graph g.m-edge.m-type path, +.m-graph g.m-node.m-type ellipse, +.m-graph g.m-node.m-type polygon, +.m-graph g.m-node.m-type polyline, +.m-graph g.m-cluster.m-type polygon { + stroke: var(--type-color); +} p, ul, ol, @@ -2854,10 +3311,7 @@ body > header > nav.m-navbar-cover:target { body > header > nav.m-navbar-landing #m-navbar-brand.m-navbar-brand-hidden { visibility: hidden; } -body - > header - > nav.m-navbar-landing:target - #m-navbar-brand.m-navbar-brand-hidden { +body > header > nav.m-navbar-landing:target #m-navbar-brand.m-navbar-brand-hidden { visibility: visible; } body > header > nav { @@ -2903,7 +3357,7 @@ body > header > nav #m-navbar-brand .m-breadcrumb { } body > header > nav a#m-navbar-show::before, body > header > nav a#m-navbar-hide::before { - content: "\2630"; + content: '\2630'; } body > header > nav #m-navbar-collapse { padding-bottom: 1rem; @@ -2943,7 +3397,7 @@ body > header > nav ol { body > header > nav ol ol { padding-left: 1.5rem; } -body > header > nav .m-row > [class*="m-col-"] { +body > header > nav .m-row > [class*='m-col-'] { padding-top: 0; padding-bottom: 0; } @@ -3189,7 +3643,7 @@ article > header p { font-size: 1.125rem; } article > header h1::after { - content: " "; + content: ' '; clear: both; display: table; } @@ -3387,56 +3841,48 @@ article section:last-child { .m-container-inflatable section:target section > .m-frame, .m-container-inflatable section:target section > .m-block, .m-container-inflatable section:target section > pre, +.m-container-inflatable section:target section > .m-code-figure > pre:first-child, +.m-container-inflatable section:target section > .m-console-figure > pre:first-child, +.m-container-inflatable section:target [class*='m-center-'] > .m-note, +.m-container-inflatable section:target [class*='m-center-'] > .m-frame, +.m-container-inflatable section:target [class*='m-center-'] > .m-block, +.m-container-inflatable section:target [class*='m-center-'] > pre, .m-container-inflatable section:target - section + [class*='m-center-'] > .m-code-figure > pre:first-child, .m-container-inflatable section:target - section + [class*='m-center-'] > .m-console-figure > pre:first-child, -.m-container-inflatable section:target [class*="m-center-"] > .m-note, -.m-container-inflatable section:target [class*="m-center-"] > .m-frame, -.m-container-inflatable section:target [class*="m-center-"] > .m-block, -.m-container-inflatable section:target [class*="m-center-"] > pre, +.m-container-inflatable section:target [class*='m-left-'] > .m-note, +.m-container-inflatable section:target [class*='m-left-'] > .m-frame, +.m-container-inflatable section:target [class*='m-left-'] > .m-block, +.m-container-inflatable section:target [class*='m-left-'] > pre, .m-container-inflatable section:target - [class*="m-center-"] + [class*='m-left-'] > .m-code-figure > pre:first-child, .m-container-inflatable section:target - [class*="m-center-"] + [class*='m-left-'] > .m-console-figure > pre:first-child, -.m-container-inflatable section:target [class*="m-left-"] > .m-note, -.m-container-inflatable section:target [class*="m-left-"] > .m-frame, -.m-container-inflatable section:target [class*="m-left-"] > .m-block, -.m-container-inflatable section:target [class*="m-left-"] > pre, +.m-container-inflatable section:target [class*='m-right-'] > .m-note, +.m-container-inflatable section:target [class*='m-right-'] > .m-frame, +.m-container-inflatable section:target [class*='m-right-'] > .m-block, +.m-container-inflatable section:target [class*='m-right-'] > pre, .m-container-inflatable section:target - [class*="m-left-"] + [class*='m-right-'] > .m-code-figure > pre:first-child, .m-container-inflatable section:target - [class*="m-left-"] - > .m-console-figure - > pre:first-child, -.m-container-inflatable section:target [class*="m-right-"] > .m-note, -.m-container-inflatable section:target [class*="m-right-"] > .m-frame, -.m-container-inflatable section:target [class*="m-right-"] > .m-block, -.m-container-inflatable section:target [class*="m-right-"] > pre, -.m-container-inflatable - section:target - [class*="m-right-"] - > .m-code-figure - > pre:first-child, -.m-container-inflatable - section:target - [class*="m-right-"] + [class*='m-right-'] > .m-console-figure > pre:first-child, .m-container-inflatable section:target .m-container-inflate > .m-note, @@ -3464,34 +3910,13 @@ article section:last-child { .m-container-inflatable section:target > .m-console-figure::before, .m-container-inflatable section:target section > .m-code-figure::before, .m-container-inflatable section:target section > .m-console-figure::before, -.m-container-inflatable - section:target - [class*="m-center-"] - > .m-code-figure::before, -.m-container-inflatable - section:target - [class*="m-center-"] - > .m-console-figure::before, -.m-container-inflatable - section:target - [class*="m-left-"] - > .m-code-figure::before, -.m-container-inflatable - section:target - [class*="m-left-"] - > .m-console-figure::before, -.m-container-inflatable - section:target - [class*="m-right-"] - > .m-code-figure::before, -.m-container-inflatable - section:target - [class*="m-right-"] - > .m-console-figure::before, -.m-container-inflatable - section:target - .m-container-inflate - > .m-code-figure::before, +.m-container-inflatable section:target [class*='m-center-'] > .m-code-figure::before, +.m-container-inflatable section:target [class*='m-center-'] > .m-console-figure::before, +.m-container-inflatable section:target [class*='m-left-'] > .m-code-figure::before, +.m-container-inflatable section:target [class*='m-left-'] > .m-console-figure::before, +.m-container-inflatable section:target [class*='m-right-'] > .m-code-figure::before, +.m-container-inflatable section:target [class*='m-right-'] > .m-console-figure::before, +.m-container-inflatable section:target .m-container-inflate > .m-code-figure::before, .m-container-inflatable section:target .m-container-inflate @@ -3557,22 +3982,10 @@ article section:last-child { border-left-width: 0; padding-left: 1rem; } - .m-container-inflatable - section:target - .m-center-s - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-center-s - > figure.m-console-figure::before, - .m-container-inflatable - section:target - .m-right-s - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-right-s - > figure.m-console-figure::before { + .m-container-inflatable section:target .m-center-s > figure.m-code-figure::before, + .m-container-inflatable section:target .m-center-s > figure.m-console-figure::before, + .m-container-inflatable section:target .m-right-s > figure.m-code-figure::before, + .m-container-inflatable section:target .m-right-s > figure.m-console-figure::before { border-top-left-radius: 0px; border-bottom-left-radius: 0px; border-left-width: 0.125rem; @@ -3630,22 +4043,10 @@ article section:last-child { border-left-width: 0; padding-left: 1rem; } - .m-container-inflatable - section:target - .m-center-m - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-center-m - > figure.m-console-figure::before, - .m-container-inflatable - section:target - .m-right-m - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-right-m - > figure.m-console-figure::before { + .m-container-inflatable section:target .m-center-m > figure.m-code-figure::before, + .m-container-inflatable section:target .m-center-m > figure.m-console-figure::before, + .m-container-inflatable section:target .m-right-m > figure.m-code-figure::before, + .m-container-inflatable section:target .m-right-m > figure.m-console-figure::before { border-top-left-radius: 0px; border-bottom-left-radius: 0px; border-left-width: 0.125rem; @@ -3703,22 +4104,10 @@ article section:last-child { border-left-width: 0; padding-left: 1rem; } - .m-container-inflatable - section:target - .m-center-l - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-center-l - > figure.m-console-figure::before, - .m-container-inflatable - section:target - .m-right-l - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-right-l - > figure.m-console-figure::before { + .m-container-inflatable section:target .m-center-l > figure.m-code-figure::before, + .m-container-inflatable section:target .m-center-l > figure.m-console-figure::before, + .m-container-inflatable section:target .m-right-l > figure.m-code-figure::before, + .m-container-inflatable section:target .m-right-l > figure.m-console-figure::before { border-top-left-radius: 0px; border-bottom-left-radius: 0px; border-left-width: 0.125rem; @@ -3727,33 +4116,30 @@ article section:last-child { .m-container-inflatable section:target > figure.m-code-figure::before, .m-container-inflatable section:target > figure.m-console-figure::before, .m-container-inflatable section:target section > figure.m-code-figure::before, +.m-container-inflatable section:target section > figure.m-console-figure::before, .m-container-inflatable section:target - section - > figure.m-console-figure::before, -.m-container-inflatable - section:target - [class*="m-center-"] + [class*='m-center-'] > figure.m-code-figure::before, .m-container-inflatable section:target - [class*="m-center-"] + [class*='m-center-'] > figure.m-console-figure::before, .m-container-inflatable section:target - [class*="m-left-"] + [class*='m-left-'] > figure.m-code-figure::before, .m-container-inflatable section:target - [class*="m-left-"] + [class*='m-left-'] > figure.m-console-figure::before, .m-container-inflatable section:target - [class*="m-right-"] + [class*='m-right-'] > figure.m-code-figure::before, .m-container-inflatable section:target - [class*="m-right-"] + [class*='m-right-'] > figure.m-console-figure::before, .m-container-inflatable section:target @@ -3766,77 +4152,38 @@ article section:last-child { border-left-color: #ddd; } @media screen and (min-width: 576px) { - .m-container-inflatable - section:target - .m-center-s - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-right-s - > figure.m-code-figure::before { + .m-container-inflatable section:target .m-center-s > figure.m-code-figure::before, + .m-container-inflatable section:target .m-right-s > figure.m-code-figure::before { border-color: #f7f7f7; } - .m-container-inflatable - section:target - .m-center-s - > figure.m-console-figure::before, - .m-container-inflatable - section:target - .m-right-s - > figure.m-console-figure::before { + .m-container-inflatable section:target .m-center-s > figure.m-console-figure::before, + .m-container-inflatable section:target .m-right-s > figure.m-console-figure::before { border-color: #f7f7f7; } } @media screen and (min-width: 768px) { - .m-container-inflatable - section:target - .m-center-m - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-right-m - > figure.m-code-figure::before { + .m-container-inflatable section:target .m-center-m > figure.m-code-figure::before, + .m-container-inflatable section:target .m-right-m > figure.m-code-figure::before { border-color: #f7f7f7; } - .m-container-inflatable - section:target - .m-center-m - > figure.m-console-figure::before, - .m-container-inflatable - section:target - .m-right-m - > figure.m-console-figure::before { + .m-container-inflatable section:target .m-center-m > figure.m-console-figure::before, + .m-container-inflatable section:target .m-right-m > figure.m-console-figure::before { border-color: #f7f7f7; } } @media screen and (min-width: 992px) { - .m-container-inflatable - section:target - .m-center-l - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-right-l - > figure.m-code-figure::before { + .m-container-inflatable section:target .m-center-l > figure.m-code-figure::before, + .m-container-inflatable section:target .m-right-l > figure.m-code-figure::before { border-color: #f7f7f7; } - .m-container-inflatable - section:target - .m-center-l - > figure.m-console-figure::before, - .m-container-inflatable - section:target - .m-right-l - > figure.m-console-figure::before { + .m-container-inflatable section:target .m-center-l > figure.m-console-figure::before, + .m-container-inflatable section:target .m-right-l > figure.m-console-figure::before { border-color: #f7f7f7; } } .m-container-inflatable section:target pre, .m-container-inflatable section:target figure.m-code-figure > pre:first-child, -.m-container-inflatable - section:target - figure.m-console-figure - > pre:first-child { +.m-container-inflatable section:target figure.m-console-figure > pre:first-child { border-color: #ddd; } .m-container-inflatable section:target .m-note.m-default { @@ -4039,45 +4386,140 @@ article section:last-child { color: #8a7b52; } -.m-console .hll { background-color: #ffffcc } -.m-console .g-AnsiBackgroundBlack { background-color: #232627 } -.m-console .g-AnsiBackgroundBlue { background-color: #1d99f3 } -.m-console .g-AnsiBackgroundBrightBlack { background-color: #7f8c8d } -.m-console .g-AnsiBackgroundBrightBlue { background-color: #3daee9 } -.m-console .g-AnsiBackgroundBrightCyan { background-color: #16a085 } -.m-console .g-AnsiBackgroundBrightGreen { background-color: #1cdc9a } -.m-console .g-AnsiBackgroundBrightMagenta { background-color: #8e44ad } -.m-console .g-AnsiBackgroundBrightRed { background-color: #c0392b } -.m-console .g-AnsiBackgroundBrightWhite { background-color: #ffffff } -.m-console .g-AnsiBackgroundBrightYellow { background-color: #fdbc4b } -.m-console .g-AnsiBackgroundCyan { background-color: #1abc9c } -.m-console .g-AnsiBackgroundDefault { background-color: #fcfcfc } -.m-console .g-AnsiBackgroundGreen { background-color: #11d116 } -.m-console .g-AnsiBackgroundMagenta { background-color: #9b59b6 } -.m-console .g-AnsiBackgroundRed { background-color: #ed1515 } -.m-console .g-AnsiBackgroundWhite { background-color: #fcfcfc } -.m-console .g-AnsiBackgroundYellow { background-color: #f67400 } -.m-console .g-AnsiBlack { color: #232627 } -.m-console .g-AnsiBlue { color: #1d99f3 } -.m-console .g-AnsiBrightBlack { color: #7f8c8d; font-weight: bold } -.m-console .g-AnsiBrightBlue { color: #3daee9; font-weight: bold } -.m-console .g-AnsiBrightCyan { color: #16a085; font-weight: bold } -.m-console .g-AnsiBrightDefault { color: #ffffff; font-weight: bold } -.m-console .g-AnsiBrightGreen { color: #1cdc9a; font-weight: bold } -.m-console .g-AnsiBrightMagenta { color: #8e44ad; font-weight: bold } -.m-console .g-AnsiBrightRed { color: #c0392b; font-weight: bold } -.m-console .g-AnsiBrightWhite { color: #ffffff; font-weight: bold } -.m-console .g-AnsiBrightYellow { color: #fdbc4b; font-weight: bold } -.m-console .g-AnsiCyan { color: #1abc9c } -.m-console .g-AnsiDefault { color: #fcfcfc } -.m-console .g-AnsiGreen { color: #11d116 } -.m-console .g-AnsiMagenta { color: #9b59b6 } -.m-console .g-AnsiRed { color: #ed1515 } -.m-console .g-AnsiWhite { color: #fcfcfc } -.m-console .g-AnsiYellow { color: #f67400 } -.m-console .go { color: #fcfcfc } -.m-console .gp { color: #16a085; font-weight: bold } -.m-console .w { color: #fcfcfc } +.m-console .hll { + background-color: #ffffcc; +} +.m-console .g-AnsiBackgroundBlack { + background-color: #232627; +} +.m-console .g-AnsiBackgroundBlue { + background-color: #1d99f3; +} +.m-console .g-AnsiBackgroundBrightBlack { + background-color: #7f8c8d; +} +.m-console .g-AnsiBackgroundBrightBlue { + background-color: #3daee9; +} +.m-console .g-AnsiBackgroundBrightCyan { + background-color: #16a085; +} +.m-console .g-AnsiBackgroundBrightGreen { + background-color: #1cdc9a; +} +.m-console .g-AnsiBackgroundBrightMagenta { + background-color: #8e44ad; +} +.m-console .g-AnsiBackgroundBrightRed { + background-color: #c0392b; +} +.m-console .g-AnsiBackgroundBrightWhite { + background-color: #ffffff; +} +.m-console .g-AnsiBackgroundBrightYellow { + background-color: #fdbc4b; +} +.m-console .g-AnsiBackgroundCyan { + background-color: #1abc9c; +} +.m-console .g-AnsiBackgroundDefault { + background-color: #fcfcfc; +} +.m-console .g-AnsiBackgroundGreen { + background-color: #11d116; +} +.m-console .g-AnsiBackgroundMagenta { + background-color: #9b59b6; +} +.m-console .g-AnsiBackgroundRed { + background-color: #ed1515; +} +.m-console .g-AnsiBackgroundWhite { + background-color: #fcfcfc; +} +.m-console .g-AnsiBackgroundYellow { + background-color: #f67400; +} +.m-console .g-AnsiBlack { + color: #232627; +} +.m-console .g-AnsiBlue { + color: #1d99f3; +} +.m-console .g-AnsiBrightBlack { + color: #7f8c8d; + font-weight: bold; +} +.m-console .g-AnsiBrightBlue { + color: #3daee9; + font-weight: bold; +} +.m-console .g-AnsiBrightCyan { + color: #16a085; + font-weight: bold; +} +.m-console .g-AnsiBrightDefault { + color: #ffffff; + font-weight: bold; +} +.m-console .g-AnsiBrightGreen { + color: #1cdc9a; + font-weight: bold; +} +.m-console .g-AnsiBrightInvertedDefault { + color: #1a1c1d; + font-weight: bold; +} +.m-console .g-AnsiBrightMagenta { + color: #8e44ad; + font-weight: bold; +} +.m-console .g-AnsiBrightRed { + color: #c0392b; + font-weight: bold; +} +.m-console .g-AnsiBrightWhite { + color: #ffffff; + font-weight: bold; +} +.m-console .g-AnsiBrightYellow { + color: #fdbc4b; + font-weight: bold; +} +.m-console .g-AnsiCyan { + color: #1abc9c; +} +.m-console .g-AnsiDefault { + color: #fcfcfc; +} +.m-console .g-AnsiGreen { + color: #11d116; +} +.m-console .g-AnsiInvertedDefault { + color: #1a1c1d; +} +.m-console .g-AnsiMagenta { + color: #9b59b6; +} +.m-console .g-AnsiRed { + color: #ed1515; +} +.m-console .g-AnsiWhite { + color: #fcfcfc; +} +.m-console .g-AnsiYellow { + color: #f67400; +} +.m-console .go { + color: #fcfcfc; +} +.m-console .gp { + color: #16a085; + font-weight: bold; +} +.m-console .w { + color: #fcfcfc; +} a.m-doc, a.m-doc-self, diff --git a/docs/mcss-Doxyfile b/docs/mcss-Doxyfile index a260c6f97..82e188fca 100644 --- a/docs/mcss-Doxyfile +++ b/docs/mcss-Doxyfile @@ -2,7 +2,7 @@ GENERATE_HTML = NO GENERATE_XML = YES XML_PROGRAMLISTING = NO -HTML_OUTPUT = ../ModularSensorsDoxygen/m.css +HTML_OUTPUT = ../ModularSensors_Doxygen/m.css SHOW_INCLUDE_FILES = YES WARN_LOGFILE = mcssDoxygenOutput.log PROJECT_REPOSITORY = https://github.com/EnviroDIY/ModularSensors @@ -18,4 +18,4 @@ ALIASES += \ "m_keyword{3}=@xmlonly@endxmlonly" \ "m_enum_values_as_keywords=@xmlonly@endxmlonly" \ "m_since{2}=@since @m_class{m-label m-success m-flat} @ref changelog-\1-\2 \"since v\1.\2\"" \ - "m_deprecated_since{3}=@since deprecated in v\1.\2.\3 @deprecated" \ No newline at end of file + "m_deprecated_since{3}=@since deprecated in v\1.\2.\3 @deprecated" diff --git a/pioScripts/generate_compile_commands.py b/pioScripts/generate_compile_commands.py index f3e9ccaa8..afec170ef 100644 --- a/pioScripts/generate_compile_commands.py +++ b/pioScripts/generate_compile_commands.py @@ -1,13 +1,15 @@ import os +import sys Import("env") -print("Generating compile commands!") +if "compiledb" not in COMMAND_LINE_TARGETS: + print("Generating compile commands!") -# include toolchain paths -env.Replace(COMPILATIONDB_INCLUDE_TOOLCHAIN=True) + # include toolchain paths + env.Replace(COMPILATIONDB_INCLUDE_TOOLCHAIN=True) -# override compilation DB path -env.Replace( - COMPILATIONDB_PATH=os.path.join("$PROJECT_DIR/.vscode", "compile_commands.json") -) + # override compilation DB path + env.Replace( + COMPILATIONDB_PATH=os.path.join("$PROJECT_DIR/.vscode", "compile_commands.json") + ) diff --git a/src/LogBuffer.h b/src/LogBuffer.h index 9d3151256..7186024a6 100644 --- a/src/LogBuffer.h +++ b/src/LogBuffer.h @@ -13,8 +13,11 @@ #ifndef SRC_LOGBUFFER_H_ #define SRC_LOGBUFFER_H_ +#ifndef MS_LOG_DATA_BUFFER_SIZE +#ifdef ARDUINO_AVR_MEGA2560 +#define MS_LOG_DATA_BUFFER_SIZE 2048 +#else /** - * @def MS_LOG_DATA_BUFFER_SIZE * @brief Log Data Buffer * * This determines how much RAM is reserved to buffer log records before @@ -25,10 +28,6 @@ * This can be changed by setting the build flag MS_LOG_DATA_BUFFER_SIZE when * compiling. 8192 bytes is a safe value for the Mayfly 1.1 with six variables. */ -#ifndef MS_LOG_DATA_BUFFER_SIZE -#ifdef ARDUINO_AVR_MEGA2560 -#define MS_LOG_DATA_BUFFER_SIZE 2048 -#else #define MS_LOG_DATA_BUFFER_SIZE 8192 #endif #endif @@ -57,14 +56,14 @@ class LogBuffer { * @brief Sets the number of variables the buffer will store in each record. * Clears the buffer as a side effect. * - * @param[in] numVariables_ The number of variables to store. + * @param numVariables_ The number of variables to store. */ void setNumVariables(uint8_t numVariables_); /** * @brief Gets the number of variables that will be stored in each record. * - * @return The variable count. + * @return The variable count. */ uint8_t getNumVariables(void); @@ -74,53 +73,53 @@ class LogBuffer { void clear(void); /** - * @brief Gets the number of records currently in the log. + * @brief Gets the number of records currently in the log. * - * @return The number of records. + * @return The number of records. */ int getNumRecords(void); /** - * @brief Computes the percentage full of the buffer. + * @brief Computes the percentage full of the buffer. * - * @return The current percent full. + * @return The current percent full. */ uint8_t getPercentFull(void); /** * @brief Adds a new record with the given timestamp. * - * @param[in] timestamp The timestamp + * @param timestamp The timestamp * - * @return Index of the new record, or -1 if there was no space. + * @return Index of the new record, or -1 if there was no space. */ int addRecord(uint32_t timestamp); /** * @brief Sets the value of a particular variable in a particular record. * - * @param[in] record The record - * @param[in] variable The variable - * @param[in] value The value + * @param record The record + * @param variable The variable + * @param value The value */ void setRecordValue(int record, uint8_t variable, float value); /** * @brief Gets the timestamp of a particular record. * - * @param[in] record The record + * @param record The record * - * @return The record's timestamp. + * @return **uint32_t** The record's timestamp. */ uint32_t getRecordTimestamp(int record); /** * @brief Gets the value of a particular variable in a particular record. * - * @param[in] record The record - * @param[in] variable The variable + * @param record The record + * @param variable The variable * - * @return The variable's value. + * @return **float** The variable's value. */ float getRecordValue(int record, uint8_t variable); diff --git a/src/LoggerBase.h b/src/LoggerBase.h index caf8480a2..93764c15d 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -1197,12 +1197,22 @@ class Logger { /** * @brief This is a one-and-done to log data + * + * @param sleepBeforeReturning True to put the logger to sleep before + * returning from the function; optional with a default value of true. + * @note If sleepBeforeReturning is set to false, the logger WILL NOT sleep + * between readings. */ virtual void logData(bool sleepBeforeReturning = true); /** * @brief This is a one-and-done to log data and publish the results to any * associated publishers. + * + * @param sleepBeforeReturning True to put the logger to sleep before + * returning from the function; optional with a default value of true. + * @note If sleepBeforeReturning is set to false, the logger WILL NOT sleep + * between readings. */ void logDataAndPublish(bool sleepBeforeReturning = true); diff --git a/src/LoggerModem.h b/src/LoggerModem.h index a5eb818cc..d7c22470e 100644 --- a/src/LoggerModem.h +++ b/src/LoggerModem.h @@ -616,6 +616,10 @@ class loggerModem { * variables. Setting this to 0b11111111 will enable polling for all modem * measured variables. * + * @param pollingBitmask The bitmask indicating which paramters to poll. + * + * @see loggerModem::_pollModemMetaData + * * @note This will **not** disable polling for any unset bits in the * provided bitmask. It will only enable those bits that are set. */ @@ -626,6 +630,10 @@ class loggerModem { * variables. Setting this to 0b11111111 will disable polling for all modem * measured variables. * + * @param pollingBitmask The bitmask indicating which paramters to poll. + * + * @see loggerModem::_pollModemMetaData + * * @note This will **not** enable polling for any unset bits in the * provided bitmask. It will only disable polling for those bits that are * set. @@ -639,6 +647,10 @@ class loggerModem { * Setting this to 0 (0b00000000) will disable polling for all metadata * parameters. Setting it to 256 (0b11111111) will enable polling for all * parameters. + * + * @param pollingBitmask The bitmask indicating which paramters to poll. + * + * @see loggerModem::_pollModemMetaData */ void setMetadataPolling(uint8_t pollingBitmask); diff --git a/src/SensorBase.h b/src/SensorBase.h index 44a1d68a3..55ef4c30c 100644 --- a/src/SensorBase.h +++ b/src/SensorBase.h @@ -350,6 +350,9 @@ class Sensor { /** * @brief Average the results of all measurements by dividing the sum of * all measurements by the number of measurements taken. + * + * @param resultNumber The position of the result within the result array. + * @param resultValue The value of the result. */ void verifyAndAddMeasurementResult(uint8_t resultNumber, int32_t resultValue); @@ -541,10 +544,10 @@ class Sensor { uint8_t _sensorStatus = 0; /** - * @brief An array for each sensor containing the variable objects tied to - * that sensor. The #MAX_NUMBER_VARS cannot be determined on a per-sensor - * basis, because of the way memory is used on an Arduino. It must be - * defined once for the whole class. + * @brief An array for each sensor containing pointers to the variable + * objects tied to that sensor. The #MAX_NUMBER_VARS cannot be determined + * on a per-sensor basis, because of the way memory is used on an Arduino. + * It must be defined once for the whole class. */ Variable* variables[MAX_NUMBER_VARS]; }; diff --git a/src/VariableArray.h b/src/VariableArray.h index 8e768aaa8..087b9f640 100644 --- a/src/VariableArray.h +++ b/src/VariableArray.h @@ -284,9 +284,33 @@ class VariableArray { uint8_t _maxSamplestoAverage; private: - bool isLastVarFromSensor(int arrayIndex); + /** + * @brief Check if the current variable is the last variable that the sensor + * will return. + * + * This is used for formating output where the format is slightly different + * for the last value. (ie, no comma after the last value) + * + * @param arrayIndex The index of the variable in the sensor variable array + * @return True if the variable is the last in the array. + */ + bool isLastVarFromSensor(int arrayIndex); + /** + * @brief Count the maximum number of measurements needed from a single + * sensor for the requested averaging + * + * @return *uint8_t* The number of measurements needed. + */ uint8_t countMaxToAverage(void); - bool checkVariableUUIDs(void); + /** + * @brief Check that all variable have valid UUID's, if they are assigned + * + * @return True if all variables have valid UUID's. + * + * @warning This does not check that the UUID's are the true UUID's for the + * variables, just that the text is a validly formed UUID. + */ + bool checkVariableUUIDs(void); #ifdef MS_VARIABLEARRAY_DEBUG_DEEP /** diff --git a/src/VariableBase.h b/src/VariableBase.h index b72c5fb19..ff078e7da 100644 --- a/src/VariableBase.h +++ b/src/VariableBase.h @@ -385,15 +385,41 @@ class Variable { private: + /** + * @brief Private reference to function used to calculate the variables + * value. + */ float (*_calcFxn)(void) = nullptr; - const uint8_t _sensorVarNum = 0; - uint8_t _decimalResolution = 0; + /** + * @brief The position in the sensor's value array of this variable's value. + */ + const uint8_t _sensorVarNum = 0; + /** + * @brief The resolution (in decimal places) of the value. + */ + uint8_t _decimalResolution = 0; + + /** + * @brief The name of the variable per the [ODM2 variable name controlled + * vocabulary](http://vocabulary.odm2.org/variablename/) + */ const char* _varName = nullptr; + /** + * @brief The unit of the variable per the [ODM2 unit controlled + * vocabulary](http://vocabulary.odm2.org/units/) + */ const char* _varUnit = nullptr; + /** + * @brief A custom code for the variable. This can be any short text + * helping to identify the variable in files. + */ const char* _varCode = nullptr; - const char* _uuid = nullptr; + /** + * @brief A universally unique identifier for the variable. + */ + const char* _uuid = nullptr; }; #endif // SRC_VARIABLEBASE_H_ diff --git a/src/WatchDogs/WatchDogAVR.h b/src/WatchDogs/WatchDogAVR.h index 30b48454f..c6d417a24 100644 --- a/src/WatchDogs/WatchDogAVR.h +++ b/src/WatchDogs/WatchDogAVR.h @@ -79,6 +79,10 @@ class extendedWatchDogAVR { static volatile uint32_t _barksUntilReset; private: + /** + * @brief Internal reference to the number of seconds of silence before the + * module is reset. + */ uint32_t _resetTime_s; }; diff --git a/src/WatchDogs/WatchDogSAMD.h b/src/WatchDogs/WatchDogSAMD.h index 9b3fe1681..d1ce73cd7 100644 --- a/src/WatchDogs/WatchDogSAMD.h +++ b/src/WatchDogs/WatchDogSAMD.h @@ -83,7 +83,14 @@ class extendedWatchDogSAMD { static volatile uint32_t _barksUntilReset; private: + /** + * @brief Wait for the SAMD processor bit sync to finish.+ + */ void inline waitForWDTBitSync(); + /** + * @brief Internal reference to the number of seconds of silence before the + * module is reset. + */ uint32_t _resetTime_s; }; diff --git a/src/dataPublisherBase.h b/src/dataPublisherBase.h index 0f3058305..4ad472351 100644 --- a/src/dataPublisherBase.h +++ b/src/dataPublisherBase.h @@ -29,8 +29,8 @@ #endif +#ifndef MS_SEND_BUFFER_SIZE /** - * @def MS_SEND_BUFFER_SIZE * @brief Send Buffer * * This determines how many characters to set out at once over the TCP @@ -40,10 +40,7 @@ * * This can be changed by setting the build flag MS_SEND_BUFFER_SIZE when * compiling. - * - * @ingroup the_publishers */ -#ifndef MS_SEND_BUFFER_SIZE #define MS_SEND_BUFFER_SIZE 750 #endif diff --git a/src/modems/DigiXBee3GBypass.h b/src/modems/DigiXBee3GBypass.h index e1e6ee4c1..fbb62bdd9 100644 --- a/src/modems/DigiXBee3GBypass.h +++ b/src/modems/DigiXBee3GBypass.h @@ -169,7 +169,7 @@ class DigiXBee3GBypass : public DigiXBee { bool isModemAwake(void) override; private: - const char* _apn; + const char* _apn; ///< Internal reference to the cellular APN }; /**@}*/ #endif // SRC_MODEMS_DIGIXBEE3GBYPASS_H_ diff --git a/src/modems/DigiXBeeCellularTransparent.h b/src/modems/DigiXBeeCellularTransparent.h index 372aee4b8..33190465e 100644 --- a/src/modems/DigiXBeeCellularTransparent.h +++ b/src/modems/DigiXBeeCellularTransparent.h @@ -204,9 +204,9 @@ class DigiXBeeCellularTransparent : public DigiXBee { bool isModemAwake(void) override; private: - const char* _apn; - const char* _user; - const char* _pwd; + const char* _apn; ///< Internal reference to the cellular APN + const char* _user; ///< Internal reference to the APN's user name + const char* _pwd; ///< Internal reference to the APN's password }; /**@}*/ #endif // SRC_MODEMS_DIGIXBEECELLULARTRANSPARENT_H_ diff --git a/src/modems/DigiXBeeLTEBypass.h b/src/modems/DigiXBeeLTEBypass.h index 6d52228bc..6a952f6a8 100644 --- a/src/modems/DigiXBeeLTEBypass.h +++ b/src/modems/DigiXBeeLTEBypass.h @@ -183,7 +183,7 @@ class DigiXBeeLTEBypass : public DigiXBee { bool isModemAwake(void) override; private: - const char* _apn; + const char* _apn; ///< Internal reference to the cellular APN }; /**@}*/ #endif // SRC_MODEMS_DIGIXBEELTEBYPASS_H_ diff --git a/src/modems/DigiXBeeWifi.h b/src/modems/DigiXBeeWifi.h index e06f94f3c..67636a489 100644 --- a/src/modems/DigiXBeeWifi.h +++ b/src/modems/DigiXBeeWifi.h @@ -188,10 +188,20 @@ class DigiXBeeWifi : public DigiXBee { bool isModemAwake(void) override; private: - const char* _ssid; - const char* _pwd; - bool _maintainAssociation; + const char* _ssid; ///< Internal reference to the WiFi SSID + const char* _pwd; ///< Internal reference to the WiFi password + /** + * @brief True to maintain association with the WiFi network while in sleep + * mode. + */ + bool _maintainAssociation; + + /** + * @brief The number of times the XBee has failed to update metadata. + * + * If this is larger than #XBEE_RESET_THRESHOLD the XBee will be reset. + */ uint16_t metadata_failure_count = 0; }; /**@}*/ diff --git a/src/modems/EspressifESP8266.h b/src/modems/EspressifESP8266.h index bfb972d02..593f5aeaf 100644 --- a/src/modems/EspressifESP8266.h +++ b/src/modems/EspressifESP8266.h @@ -266,9 +266,17 @@ class EspressifESP8266 : public loggerModem { bool isModemAwake(void) override; private: + /** + * @brief Waits for the Espressif module to reboot and print out it's boot + * up string. Because the boot up string is at a different baud rate (74880 + * baud), it usually comes out as junk. + * + * @return *true* Text (assumed to be the start message) was received + * @return *false* No boot text was receivedd + */ bool ESPwaitForBoot(void); - const char* _ssid; - const char* _pwd; + const char* _ssid; ///< Internal reference to the WiFi SSID + const char* _pwd; ///< Internal reference to the WiFi password }; /** diff --git a/src/modems/LoggerModemMacros.h b/src/modems/LoggerModemMacros.h index a93d7a5d1..167e8883d 100644 --- a/src/modems/LoggerModemMacros.h +++ b/src/modems/LoggerModemMacros.h @@ -365,6 +365,8 @@ * connection to be made, if possible. * * @param specificModem The modem subclass + * @param auto_reconnect_time The amount of time, in milliseconds, to allow the + * modem to attempt to connect automatically from saved credentials. * * @return The text of a connectInternet(uint32_t maxConnectionTime) function * specific to a single modem subclass. diff --git a/src/modems/QuectelBG96.h b/src/modems/QuectelBG96.h index 771bfc795..f7b0e5284 100644 --- a/src/modems/QuectelBG96.h +++ b/src/modems/QuectelBG96.h @@ -228,7 +228,7 @@ class QuectelBG96 : public loggerModem { bool isModemAwake(void) override; private: - const char* _apn; + const char* _apn; ///< Internal reference to the cellular APN }; /**@}*/ #endif // SRC_MODEMS_QUECTELBG96_H_ diff --git a/src/modems/SIMComSIM7000.h b/src/modems/SIMComSIM7000.h index 8b455ef3b..b4f71f6c8 100644 --- a/src/modems/SIMComSIM7000.h +++ b/src/modems/SIMComSIM7000.h @@ -217,7 +217,7 @@ class SIMComSIM7000 : public loggerModem { bool isModemAwake(void) override; private: - const char* _apn; + const char* _apn; ///< Internal reference to the cellular APN }; /**@}*/ #endif // SRC_MODEMS_SIMCOMSIM7000_H_ diff --git a/src/modems/SIMComSIM7080.h b/src/modems/SIMComSIM7080.h index 3dd120371..e7847924f 100644 --- a/src/modems/SIMComSIM7080.h +++ b/src/modems/SIMComSIM7080.h @@ -212,7 +212,7 @@ class SIMComSIM7080 : public loggerModem { bool isModemAwake(void) override; private: - const char* _apn; + const char* _apn; ///< Internal reference to the cellular APN }; /**@}*/ #endif // SRC_MODEMS_SIMCOMSIM7080_H_ diff --git a/src/modems/SIMComSIM800.h b/src/modems/SIMComSIM800.h index d5e97dc07..dfdceab8b 100644 --- a/src/modems/SIMComSIM800.h +++ b/src/modems/SIMComSIM800.h @@ -219,7 +219,7 @@ class SIMComSIM800 : public loggerModem { bool isModemAwake(void) override; private: - const char* _apn; + const char* _apn; ///< Internal reference to the cellular APN }; /**@}*/ #endif // SRC_MODEMS_SIMCOMSIM800_H_ diff --git a/src/modems/SequansMonarch.h b/src/modems/SequansMonarch.h index 8d9f1bc21..2162c2412 100644 --- a/src/modems/SequansMonarch.h +++ b/src/modems/SequansMonarch.h @@ -250,7 +250,7 @@ class SequansMonarch : public loggerModem { bool isModemAwake(void) override; private: - const char* _apn; + const char* _apn; ///< Internal reference to the cellular APN }; /**@}*/ #endif // SRC_MODEMS_SEQUANSMONARCH_H_ diff --git a/src/modems/Sodaq2GBeeR6.h b/src/modems/Sodaq2GBeeR6.h index 07302642b..53a6f459d 100644 --- a/src/modems/Sodaq2GBeeR6.h +++ b/src/modems/Sodaq2GBeeR6.h @@ -166,6 +166,10 @@ class Sodaq2GBeeR6 : public SIMComSIM800 { bool extraModemSetup(void) override; private: + /** + * @brief The digital pin number of a pin on the mcu controlling the voltage + * reference (pin 1) for the GPRSBee. + */ int8_t _vRefPin; }; /**@}*/ diff --git a/src/modems/SodaqUBeeR410M.h b/src/modems/SodaqUBeeR410M.h index 1a25f37d3..9539a01d1 100644 --- a/src/modems/SodaqUBeeR410M.h +++ b/src/modems/SodaqUBeeR410M.h @@ -338,7 +338,7 @@ class SodaqUBeeR410M : public loggerModem { bool isModemAwake(void) override; private: - const char* _apn; + const char* _apn; ///< Internal reference to the cellular APN }; /**@}*/ #endif // SRC_MODEMS_SODAQUBEER410M_H_ diff --git a/src/modems/SodaqUBeeU201.h b/src/modems/SodaqUBeeU201.h index d09067456..dc7edc3b0 100644 --- a/src/modems/SodaqUBeeU201.h +++ b/src/modems/SodaqUBeeU201.h @@ -225,7 +225,7 @@ class SodaqUBeeU201 : public loggerModem { bool isModemAwake(void) override; private: - const char* _apn; + const char* _apn; ///< Internal reference to the cellular APN }; /**@}*/ #endif // SRC_MODEMS_SODAQUBEEU201_H_ diff --git a/src/publishers/DreamHostPublisher.h b/src/publishers/DreamHostPublisher.h index 34a5690ed..d17b302a2 100644 --- a/src/publishers/DreamHostPublisher.h +++ b/src/publishers/DreamHostPublisher.h @@ -153,6 +153,9 @@ class DreamHostPublisher : public dataPublisher { private: + /** + * @brief A pointer to the base URL for the dreamhost portal. + */ const char* _DreamHostPortalRX = nullptr; bool _dualPost = true; }; diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index 025dc80ad..32e2cc45c 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -113,7 +113,7 @@ class EnviroDIYPublisher : public dataPublisher { /** * @brief Get the EnviroDIY/Monitor My Watershed web host * - * @return *String* The EnviroDIY/Monitor My Watershed web host + * @return **String** The EnviroDIY/Monitor My Watershed web host */ String getHost(void); @@ -127,7 +127,7 @@ class EnviroDIYPublisher : public dataPublisher { /** * @brief Get the EnviroDIY/Monitor My Watershed API path * - * @return *String* The EnviroDIY/Monitor My Watershed API path + * @return **String** The EnviroDIY/Monitor My Watershed API path */ String getPath(void); /** @@ -140,7 +140,7 @@ class EnviroDIYPublisher : public dataPublisher { /** * @brief Get the EnviroDIY/Monitor My Watershed API port * - * @return *int* The EnviroDIY/Monitor My Watershed API port + * @return **int** The EnviroDIY/Monitor My Watershed API port */ int getPort(void); /** @@ -234,19 +234,37 @@ class EnviroDIYPublisher : public dataPublisher { */ static const char* samplingFeatureTag; ///< The JSON feature UUID tag static const char* timestampTag; ///< The JSON feature timestamp tag - /**@}*/ - LogBuffer _logBuffer; + /**@}*/ + + + LogBuffer _logBuffer; ///< Internal reference to the logger buffer // actually transmit rather than just buffer data + /** + * @brief Transmit data from the data buffer to an external site + * + * @param outClient The client to publish the data over + * @return **int16_t** The HTTP response code from the publish attempt + * + * @note A 504 will be returned automatically if the server does not + * respond within 30 seconds. + */ int16_t flushDataBuffer(Client* outClient); - // we send every one of the first five data points immediately for field - // validation + /** + * @brief The number of transmissions remaing at the single minute intervals + * + * We send every one of the first five data points at only one minute + * intervals for faster in-field validation. + */ uint8_t _initialTransmissionsRemaining = 5; private: - // Tokens and UUID's for EnviroDIY + /** + * @brief Internal reference to the EnviroDIY/Monitor My Watershed + * registration token. + */ const char* _registrationToken = nullptr; }; diff --git a/src/publishers/ThingSpeakPublisher.h b/src/publishers/ThingSpeakPublisher.h index 511c766fb..395cbb268 100644 --- a/src/publishers/ThingSpeakPublisher.h +++ b/src/publishers/ThingSpeakPublisher.h @@ -203,9 +203,22 @@ class ThingSpeakPublisher : public dataPublisher { private: // Keys for ThingSpeak - const char* _thingSpeakMQTTKey = nullptr; - const char* _thingSpeakChannelID = nullptr; - const char* _thingSpeakChannelKey = nullptr; + /** + * @brief The MQTT key for ThingSpeak + */ + const char* _thingSpeakMQTTKey = nullptr; + /** + * @brief The channel ID for ThingSpeak + */ + const char* _thingSpeakChannelID = nullptr; + /** + * @brief The channel key for ThingSpeak + */ + const char* _thingSpeakChannelKey = nullptr; + /** + * @brief Internal reference ot the PubSubClient instance for MQTT + * communication. + */ PubSubClient _mqttClient; }; diff --git a/src/publishers/UbidotsPublisher.h b/src/publishers/UbidotsPublisher.h index 61e335f05..5b39270bb 100644 --- a/src/publishers/UbidotsPublisher.h +++ b/src/publishers/UbidotsPublisher.h @@ -195,6 +195,12 @@ class UbidotsPublisher : public dataPublisher { private: // Tokens for Ubidots + /** + * @brief The authentication token from Ubdots, either the Organization's + * Integration Token (under Users > Organization menu, visible by Admin + * only) OR the STEM User's Device Token (under the specific device's setup + * panel). + */ const char* _authentificationToken = nullptr; }; diff --git a/src/sensors/AOSongAM2315.h b/src/sensors/AOSongAM2315.h index 2788b5842..7fa3b61c0 100644 --- a/src/sensors/AOSongAM2315.h +++ b/src/sensors/AOSongAM2315.h @@ -234,7 +234,10 @@ class AOSongAM2315 : public Sensor { * @brief An internal reference to the hardware Wire instance. */ TwoWire* _i2c; - Adafruit_AM2315* am2315ptr; // create a sensor object + /** + * @brief Internal reference to the Adafruit sensor class + */ + Adafruit_AM2315* am2315ptr; }; diff --git a/src/sensors/AOSongDHT.h b/src/sensors/AOSongDHT.h index 45e99f55e..8fc8051d3 100644 --- a/src/sensors/AOSongDHT.h +++ b/src/sensors/AOSongDHT.h @@ -247,8 +247,8 @@ class AOSongDHT : public Sensor { bool addSingleMeasurementResult(void) override; private: - DHT dht_internal; - uint8_t _dhtType; + DHT dht_internal; ///< Internal reference to the Adafruit DHT object + uint8_t _dhtType; ///< Internal reference to the DHT type }; diff --git a/src/sensors/ApogeeSQ212.h b/src/sensors/ApogeeSQ212.h index c2b4d3c24..98205325c 100644 --- a/src/sensors/ApogeeSQ212.h +++ b/src/sensors/ApogeeSQ212.h @@ -267,7 +267,13 @@ class ApogeeSQ212 : public Sensor { bool addSingleMeasurementResult(void) override; private: + /** + * @brief Internal reference to the ADS channel number of the Apogee SQ-212 + */ uint8_t _adsChannel; + /** + * @brief Internal reference to the I2C address of the TI-ADS1x15 + */ uint8_t _i2cAddress; }; diff --git a/src/sensors/CampbellOBS3.h b/src/sensors/CampbellOBS3.h index bfe92c782..9a00969b7 100644 --- a/src/sensors/CampbellOBS3.h +++ b/src/sensors/CampbellOBS3.h @@ -270,8 +270,17 @@ class CampbellOBS3 : public Sensor { bool addSingleMeasurementResult(void) override; private: + /** + * @brief Internal reference to the ADS channel number of the Campbell OBS + * 3+ + */ uint8_t _adsChannel; - float _x2_coeff_A, _x1_coeff_B, _x0_coeff_C; + float _x2_coeff_A; ///< Internal reference to the x^2 coefficient + float _x1_coeff_B; ///< Internal reference to the x coefficient + float _x0_coeff_C; ///< Internal reference to the x^0 coefficient + /** + * @brief Internal reference to the I2C address of the TI-ADS1x15 + */ uint8_t _i2cAddress; }; @@ -315,6 +324,9 @@ class CampbellOBS3_Turbidity : public Variable { : Variable((const uint8_t)OBS3_TURB_VAR_NUM, (uint8_t)OBS3_RESOLUTION, OBS3_TURB_VAR_NAME, OBS3_TURB_UNIT_NAME, OBS3_TURB_DEFAULT_CODE) {} + /** + * @brief Destroy the Campbell OBS3 Turbidity object + */ ~CampbellOBS3_Turbidity() {} }; diff --git a/src/sensors/GroPointGPLP8.h b/src/sensors/GroPointGPLP8.h index 869ea74b3..f6a4a97a1 100644 --- a/src/sensors/GroPointGPLP8.h +++ b/src/sensors/GroPointGPLP8.h @@ -26,7 +26,7 @@ * Profiling Probe. Classes for the GroPoint Profile GPLP-8 Soil Moisture & * Temperature Probe. * - * @ingroup GroPoint_group + * @ingroup gropoint_group * * @tableofcontents * @m_footernavigation diff --git a/src/sensors/GroPointParent.h b/src/sensors/GroPointParent.h index 8a27f0b59..069a3c43e 100644 --- a/src/sensors/GroPointParent.h +++ b/src/sensors/GroPointParent.h @@ -200,12 +200,33 @@ class GroPointParent : public Sensor { bool addSingleMeasurementResult(void) override; private: - gropoint _gsensor; + /** + * @brief Private reference to the gropoint class for communication with the + * GroPoint sensor. + */ + gropoint _gsensor; + /** + * @brief Private reference to the model of GroPoint sensor + */ gropointModel _model; - byte _modbusAddress; - Stream* _stream; - int8_t _RS485EnablePin; - int8_t _powerPin2; + /** + * @brief Private reference to the GroPoint sensor's modbus address + */ + byte _modbusAddress; + /** + * @brief Private reference to the stream for communciation with the + * GroPoint sensor. + */ + Stream* _stream; + /** + * @brief Private reference to the RS-485 adapter's flow direction control + * pin. + */ + int8_t _RS485EnablePin; + /** + * @brief Private reference to the power pin fro the RS-485 adapter. + */ + int8_t _powerPin2; }; #endif // SRC_SENSORS_GROPOINTPARENT_H_ diff --git a/src/sensors/InSituTrollSdi12a.h b/src/sensors/InSituTrollSdi12a.h index b8031cd84..bd2368442 100644 --- a/src/sensors/InSituTrollSdi12a.h +++ b/src/sensors/InSituTrollSdi12a.h @@ -240,12 +240,18 @@ class InSituTrollSdi12a : public SDI12Sensors { "InSituTrollSdi12a", ITROLLA_NUM_VARIABLES, ITROLLA_WARM_UP_TIME_MS, ITROLLA_STABILIZATION_TIME_MS, ITROLLA_MEASUREMENT_TIME_MS) {} + /** + * @copydoc InSituTrollSdi12a::InSituTrollSdi12a + */ InSituTrollSdi12a(char* SDI12address, int8_t powerPin, int8_t dataPin, uint8_t measurementsToAverage = 1) : SDI12Sensors(SDI12address, powerPin, dataPin, measurementsToAverage, "InSituTrollSdi12a", ITROLLA_NUM_VARIABLES, ITROLLA_WARM_UP_TIME_MS, ITROLLA_STABILIZATION_TIME_MS, ITROLLA_MEASUREMENT_TIME_MS) {} + /** + * @copydoc InSituTrollSdi12a::InSituTrollSdi12a + */ InSituTrollSdi12a(int SDI12address, int8_t powerPin, int8_t dataPin, uint8_t measurementsToAverage = 1) : SDI12Sensors(SDI12address, powerPin, dataPin, measurementsToAverage, diff --git a/src/sensors/KellerAcculevel.h b/src/sensors/KellerAcculevel.h index 45e81a439..08a99b472 100644 --- a/src/sensors/KellerAcculevel.h +++ b/src/sensors/KellerAcculevel.h @@ -177,7 +177,9 @@ class KellerAcculevel : public KellerParent { measurementsToAverage, Acculevel_kellerModel, "KellerAcculevel", KELLER_NUM_VARIABLES, ACCULEVEL_WARM_UP_TIME_MS, ACCULEVEL_STABILIZATION_TIME_MS, ACCULEVEL_MEASUREMENT_TIME_MS) {} - // Destructor + /** + * @brief Destroy the Keller Acculevel object + */ ~KellerAcculevel() {} }; diff --git a/src/sensors/KellerNanolevel.h b/src/sensors/KellerNanolevel.h index bcffae086..67c9a3782 100644 --- a/src/sensors/KellerNanolevel.h +++ b/src/sensors/KellerNanolevel.h @@ -169,7 +169,9 @@ class KellerNanolevel : public KellerParent { measurementsToAverage, Nanolevel_kellerModel, "KellerNanolevel", KELLER_NUM_VARIABLES, NANOLEVEL_WARM_UP_TIME_MS, NANOLEVEL_STABILIZATION_TIME_MS, NANOLEVEL_MEASUREMENT_TIME_MS) {} - // Destructor + /** + * @brief Destroy the Keller Nanolevel object + */ ~KellerNanolevel() {} }; diff --git a/src/sensors/KellerParent.h b/src/sensors/KellerParent.h index 98e7c70b1..918d7b610 100644 --- a/src/sensors/KellerParent.h +++ b/src/sensors/KellerParent.h @@ -250,12 +250,33 @@ class KellerParent : public Sensor { bool addSingleMeasurementResult(void) override; private: - keller _ksensor; + /** + * @brief Private reference to the keller class for communication with the + * Keller sensor. + */ + keller _ksensor; + /** + * @brief Private reference to the model of Keller sensor + */ kellerModel _model; + /** + * @brief Private reference to the Keller sensor's modbus address + */ byte _modbusAddress; + /** + * @brief Private reference to the stream for communciation with the + * Keller sensor. + */ Stream* _stream; - int8_t _RS485EnablePin; - int8_t _powerPin2; + /** + * @brief Private reference to the RS-485 adapter's flow direction control + * pin. + */ + int8_t _RS485EnablePin; + /** + * @brief Private reference to the power pin fro the RS-485 adapter. + */ + int8_t _powerPin2; }; /**@}*/ #endif // SRC_SENSORS_KELLERPARENT_H_ diff --git a/src/sensors/MaxBotixSonar.h b/src/sensors/MaxBotixSonar.h index 45f7d3f63..aec7c2aa2 100644 --- a/src/sensors/MaxBotixSonar.h +++ b/src/sensors/MaxBotixSonar.h @@ -247,9 +247,17 @@ class MaxBotixSonar : public Sensor { bool addSingleMeasurementResult(void) override; private: - int16_t _maxRange; - int8_t _triggerPin; - bool _convertCm; + int16_t _maxRange; ///< The maximum range of the Maxbotix sonar + int8_t _triggerPin; ///< The pin to trigger the Maxbotix sonar + /** + * @brief True to convert the output from the Maxbotix from centimeters to + * millimeters. + */ + bool _convertCm; + /** + * @brief Private reference to the stream for communciation with the + * Maxbotix sensor. + */ Stream* _stream; }; diff --git a/src/sensors/MaximDS18.h b/src/sensors/MaximDS18.h index 09562d726..e5785f4c4 100644 --- a/src/sensors/MaximDS18.h +++ b/src/sensors/MaximDS18.h @@ -249,15 +249,32 @@ class MaximDS18 : public Sensor { bool addSingleMeasurementResult(void) override; private: + /** + * @brief Internal reference to the OneWire device address. + * + */ DeviceAddress _OneWireAddress; + /** + * @brief True to indicate that the address of the OneWire device was + * specified. If false, the first device to respond will be the one used. + */ bool _addressKnown; - // Setup an internal OneWire instance to communicate with any OneWire - // devices (not just Maxim/Dallas temperature ICs) + /** + * @brief An internal OneWire instance to communicate with any OneWire + * devices (not just Maxim/Dallas temperature ICs) + */ OneWire _internalOneWire; - // Set up the internal a "Dallas Temperature" instance for communication - // specifically with the temperature sensors. + /** + * @brief The internal "Dallas Temperature" instance for communication + * specifically with the temperature sensors. + */ DallasTemperature _internalDallasTemp; - // Turns the address into a printable string + /** + * @brief Turns the address into a printable string + * + * @param OneWireAddress The one wire address as a DeviceAddress object + * @return *String* A pretty string version of the OneWire device address. + */ String makeAddressString(DeviceAddress OneWireAddress); }; diff --git a/src/sensors/ProcessorStats.h b/src/sensors/ProcessorStats.h index 34b4d95ff..38be597e7 100644 --- a/src/sensors/ProcessorStats.h +++ b/src/sensors/ProcessorStats.h @@ -235,9 +235,9 @@ class ProcessorStats : public Sensor { bool addSingleMeasurementResult(void) override; private: - const char* _version; - int8_t _batteryPin; - int16_t sampNum = 0; + const char* _version; ///< Internal reference to the board version + int8_t _batteryPin; ///< Internal reference to the battery pin + int16_t sampNum = 0; ///< The current sample number }; diff --git a/src/sensors/SDI12Sensors.h b/src/sensors/SDI12Sensors.h index d779a8591..46fea846c 100644 --- a/src/sensors/SDI12Sensors.h +++ b/src/sensors/SDI12Sensors.h @@ -290,10 +290,10 @@ class SDI12Sensors : public Sensor { int8_t _extraWakeTime; private: - String _sensorVendor; - String _sensorModel; - String _sensorVersion; - String _sensorSerialNumber; + String _sensorVendor; ///< The vendor (manufacturer) of the SDI-12 sensor + String _sensorModel; ///< The model of the SDI-12 sensor + String _sensorVersion; ///< The version of the SDI-12 sensor + String _sensorSerialNumber; ///< The serial number of the SDI-12 sensor }; #endif // SRC_SENSORS_SDI12SENSORS_H_ diff --git a/src/sensors/TIADS1x15.h b/src/sensors/TIADS1x15.h index cc13be6f7..af75c6802 100644 --- a/src/sensors/TIADS1x15.h +++ b/src/sensors/TIADS1x15.h @@ -287,8 +287,18 @@ class TIADS1x15 : public Sensor { bool addSingleMeasurementResult(void) override; private: + /** + * @brief Internal reference to the ADS channel number of the device + * attached to the TI-ADS1x15 + */ uint8_t _adsChannel; + /** + * @brief Internal reference to the gain setting for the TI-ADS1x15 + */ float _gain; + /** + * @brief Internal reference to the I2C address of the TI-ADS1x15 + */ uint8_t _i2cAddress; }; diff --git a/src/sensors/TurnerCyclops.h b/src/sensors/TurnerCyclops.h index 753e61433..0071dfb03 100644 --- a/src/sensors/TurnerCyclops.h +++ b/src/sensors/TurnerCyclops.h @@ -329,8 +329,31 @@ class TurnerCyclops : public Sensor { bool addSingleMeasurementResult(void) override; private: + /** + * @brief Internal reference to the ADS channel number of the Turner Cyclops + */ uint8_t _adsChannel; - float _conc_std, _volt_std, _volt_blank; + /** + * @brief The concentration of the standard used for a 1-point sensor + * calibration. The concentration units should be the same as the final + * measuring units. + */ + float _conc_std; + /** + * @brief The voltage (in volts) measured for the conc_std. This voltage + * should be the final voltage *after* accounting for any voltage dividers + * or gain settings. + */ + float _volt_std; + /** + * @brief The voltage (in volts) measured for a blank. This voltage should + * be the final voltage *after* accounting for any voltage dividers or gain + * settings. + */ + float _volt_blank; + /** + * @brief Internal reference to the I2C address of the TI-ADS1x15 + */ uint8_t _i2cAddress; }; @@ -379,7 +402,7 @@ class TurnerCyclops_Voltage : public Variable { CYCLOPS_VOLTAGE_VAR_NAME, CYCLOPS_VOLTAGE_UNIT_NAME, CYCLOPS_VOLTAGE_DEFAULT_CODE) {} /** - * @brief Destroy the TurnerCyclops_Voltage object - no action needed. + * @brief Destroy the Turner Cyclops Voltage object - no action needed. */ ~TurnerCyclops_Voltage() {} }; @@ -435,6 +458,10 @@ class TurnerCyclops_Chlorophyll : public Variable { : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "chlorophyllFluorescence", "microgramPerLiter", "CyclopsChlorophyll") {} + /** + * @brief Destroy the Turner Cyclops Chlorophyll variable object - no action + * needed. + */ ~TurnerCyclops_Chlorophyll() {} }; @@ -488,6 +515,10 @@ class TurnerCyclops_Rhodamine : public Variable { : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "RhodamineFluorescence", "partPerBillion", "CyclopsRhodamine") {} + /** + * @brief Destroy the Turner Cyclops Rhodamine variable object - no action + * needed. + */ ~TurnerCyclops_Rhodamine() {} }; @@ -540,6 +571,9 @@ class TurnerCyclops_Fluorescein : public Variable { TurnerCyclops_Fluorescein() : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "fluorescein", "partPerBillion", "CyclopsFluorescein") {} + /** + * @brief Destroy the Turner Cyclops Fluorescein variable object - no action needed. + */ ~TurnerCyclops_Fluorescein() {} }; @@ -595,6 +629,10 @@ class TurnerCyclops_Phycocyanin : public Variable { : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "blue_GreenAlgae_Cyanobacteria_Phycocyanin", "partPerBillion", "CyclopsPhycocyanin") {} + /** + * @brief Destroy the Turner Cyclops Phycocyanin variable object - no action + * needed. + */ ~TurnerCyclops_Phycocyanin() {} }; @@ -648,6 +686,10 @@ class TurnerCyclops_Phycoerythrin : public Variable { TurnerCyclops_Phycoerythrin() : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "phycoerythrin", "partPerBillion", "CyclopsPhycoerythrin") {} + /** + * @brief Destroy the Turner Cyclops Phycoerythrin variable object - no + * action needed. + */ ~TurnerCyclops_Phycoerythrin() {} }; @@ -706,6 +748,10 @@ class TurnerCyclops_CDOM : public Variable { : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "fluorescenceDissolvedOrganicMatter", "partPerBillion", "CyclopsCDOM") {} + /** + * @brief Destroy the Turner Cyclops CDOM variable object - no action + * needed. + */ ~TurnerCyclops_CDOM() {} }; @@ -761,6 +807,10 @@ class TurnerCyclops_CrudeOil : public Variable { : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "petroleumHydrocarbonTotal", "partPerBillion", "CyclopsCrudeOil") {} + /** + * @brief Destroy the Turner Cyclops CrudeOil variable object - no action + * needed. + */ ~TurnerCyclops_CrudeOil() {} }; @@ -817,6 +867,9 @@ class TurnerCyclops_Brighteners : public Variable { : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "opticalBrighteners", "partPerBillion", "CyclopsOpticalBrighteners") {} + /** + * @brief Destroy the Turner Cyclops Brighteners object - no action needed. + */ ~TurnerCyclops_Brighteners() {} }; @@ -870,6 +923,10 @@ class TurnerCyclops_Turbidity : public Variable { : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "Turbidity", "nephelometricTurbidityUnit", "CyclopsTurbidity") {} + /** + * @brief Destroy the Turner Cyclops Turbidity variable object - no action + * needed. + */ ~TurnerCyclops_Turbidity() {} }; @@ -923,6 +980,10 @@ class TurnerCyclops_PTSA : public Variable { TurnerCyclops_PTSA() : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "ptsa", "partPerBillion", "CyclopsPTSA") {} + /** + * @brief Destroy the Turner Cyclops PTSA variable object - no action + * needed. + */ ~TurnerCyclops_PTSA() {} }; @@ -976,6 +1037,10 @@ class TurnerCyclops_BTEX : public Variable { TurnerCyclops_BTEX() : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "btex", "partPerMillion", "CyclopsBTEX") {} + /** + * @brief Destroy the Turner Cyclops BTEX variable object - no action + * needed. + */ ~TurnerCyclops_BTEX() {} }; @@ -1028,6 +1093,10 @@ class TurnerCyclops_Tryptophan : public Variable { TurnerCyclops_Tryptophan() : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "tryptophan", "partPerBillion", "CyclopsTryptophan") {} + /** + * @brief Destroy the Turner Cyclops Tryptophan variable object - no action + * needed. + */ ~TurnerCyclops_Tryptophan() {} }; @@ -1082,6 +1151,10 @@ class TurnerCyclops_RedChlorophyll : public Variable { : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "chlorophyllFluorescence", "microgramPerLiter", "CyclopsRedChlorophyll") {} + /** + * @brief Destroy the Turner Cyclops Red Chlorophyll variable object - no + * action needed. + */ ~TurnerCyclops_RedChlorophyll() {} }; /**@}*/ diff --git a/src/sensors/YosemitechParent.h b/src/sensors/YosemitechParent.h index b034177b1..3dcb70328 100644 --- a/src/sensors/YosemitechParent.h +++ b/src/sensors/YosemitechParent.h @@ -253,12 +253,33 @@ class YosemitechParent : public Sensor { bool addSingleMeasurementResult(void) override; private: - yosemitech _ysensor; + /** + * @brief Private reference to the yosemitech class for communication with + * the Yosemitech sensor. + */ + yosemitech _ysensor; + /** + * @brief Private reference to the model of Yosemitech Sensor + */ yosemitechModel _model; + /** + * @brief Private reference to the Yosemitech sensor's modbus address + */ byte _modbusAddress; + /** + * @brief Private reference to the stream for communciation with the + * Yosemitech sensor. + */ Stream* _stream; - int8_t _RS485EnablePin; - int8_t _powerPin2; + /** + * @brief Private reference to the RS-485 adapter's flow direction control + * pin. + */ + int8_t _RS485EnablePin; + /** + * @brief Private reference to the power pin fro the RS-485 adapter. + */ + int8_t _powerPin2; }; #endif // SRC_SENSORS_YOSEMITECHPARENT_H_ From 5e0a073af527a763e4ae469b783a01e8182f121d Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 11 Jun 2024 13:14:46 -0400 Subject: [PATCH 073/138] Remove unused members Signed-off-by: Sara Damiano --- src/publishers/DreamHostPublisher.h | 1 - src/sensors/AnalogElecConductivity.cpp | 8 +++----- src/sensors/AnalogElecConductivity.h | 5 ----- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/publishers/DreamHostPublisher.h b/src/publishers/DreamHostPublisher.h index d17b302a2..243e46038 100644 --- a/src/publishers/DreamHostPublisher.h +++ b/src/publishers/DreamHostPublisher.h @@ -157,7 +157,6 @@ class DreamHostPublisher : public dataPublisher { * @brief A pointer to the base URL for the dreamhost portal. */ const char* _DreamHostPortalRX = nullptr; - bool _dualPost = true; }; #endif // SRC_PUBLISHERS_DREAMHOSTPUBLISHER_H_ diff --git a/src/sensors/AnalogElecConductivity.cpp b/src/sensors/AnalogElecConductivity.cpp index e1b49b01e..397afb7dc 100644 --- a/src/sensors/AnalogElecConductivity.cpp +++ b/src/sensors/AnalogElecConductivity.cpp @@ -22,8 +22,6 @@ AnalogElecConductivity::AnalogElecConductivity(int8_t powerPin, int8_t dataPin, ANALOGELECCONDUCTIVITY_STABILIZATION_TIME_MS, ANALOGELECCONDUCTIVITY_MEASUREMENT_TIME_MS, powerPin, dataPin, measurementsToAverage, ANALOGELECCONDUCTIVITY_INC_CALC_VARIABLES), - _EcPowerPin(powerPin), - _EcAdcPin(dataPin), _Rseries_ohms(Rseries_ohms), _sensorEC_Konst(sensorEC_Konst) {} // Destructor @@ -31,13 +29,13 @@ AnalogElecConductivity::~AnalogElecConductivity() {} String AnalogElecConductivity::getSensorLocation(void) { String sensorLocation = F("anlgEc Proc Data/Pwr"); - sensorLocation += String(_EcAdcPin) + "/" + String(_EcPowerPin); + sensorLocation += String(_dataPin) + "/" + String(_powerPin); return sensorLocation; } float AnalogElecConductivity::readEC() { - return readEC(_EcAdcPin); + return readEC(_dataPin); } @@ -92,7 +90,7 @@ bool AnalogElecConductivity::addSingleMeasurementResult(void) { if (bitRead(_sensorStatus, 6)) { MS_DBG(getSensorNameAndLocation(), F("is reporting:")); - sensorEC_uScm = readEC(_EcAdcPin); + sensorEC_uScm = readEC(_dataPin); MS_DBG(F("Water EC (uSm/cm)"), sensorEC_uScm); } else { MS_DBG(getSensorNameAndLocation(), F("is not currently measuring!")); diff --git a/src/sensors/AnalogElecConductivity.h b/src/sensors/AnalogElecConductivity.h index 57351fe86..19bba3a36 100644 --- a/src/sensors/AnalogElecConductivity.h +++ b/src/sensors/AnalogElecConductivity.h @@ -381,11 +381,6 @@ class AnalogElecConductivity : public Sensor { float readEC(uint8_t analogPinNum); private: - int8_t _EcPowerPin; - int8_t _EcAdcPin; - - float* _ptrWaterTemperature_C; - /// @brief The resistance of the circiut resistor plus any series port /// resistance float _Rseries_ohms = RSERIES_OHMS_DEF; From bdf5fa830b6318bbe6d0f6485390181d6097a307 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 11 Jun 2024 13:21:46 -0400 Subject: [PATCH 074/138] Change to reusable workflows Signed-off-by: Sara Damiano --- .github/workflows/build_documentation.yaml | 135 +------ .github/workflows/build_examples.yaml | 235 +----------- .github/workflows/changelog_reminder.yaml | 2 +- .github/workflows/prepare_release.yaml | 160 +------- .../workflows/verify_library_structure.yaml | 96 +---- .gitignore | 2 + continuous_integration/arduino_cli.yaml | 22 -- .../beautify_arduino_lint_log.py | 42 --- .../build-install-doxygen.sh | 61 --- continuous_integration/copy-doc-sources.sh | 46 --- .../generate-documentation.sh | 43 --- .../install-test-version-arduino-cli.sh | 44 --- continuous_integration/requirements.txt | 5 - continuous_integration/validate_manifest.py | 19 - docs/copyFunctions.py | 101 ----- docs/fixFunctionsInGroups.py | 98 ----- docs/fixSectionsInXml.py | 137 ------- docs/markdown_prefilter.py | 355 ------------------ 18 files changed, 28 insertions(+), 1575 deletions(-) delete mode 100644 continuous_integration/arduino_cli.yaml delete mode 100644 continuous_integration/beautify_arduino_lint_log.py delete mode 100644 continuous_integration/build-install-doxygen.sh delete mode 100644 continuous_integration/copy-doc-sources.sh delete mode 100644 continuous_integration/generate-documentation.sh delete mode 100644 continuous_integration/install-test-version-arduino-cli.sh delete mode 100644 continuous_integration/requirements.txt delete mode 100644 continuous_integration/validate_manifest.py delete mode 100644 docs/copyFunctions.py delete mode 100644 docs/fixFunctionsInGroups.py delete mode 100644 docs/fixSectionsInXml.py delete mode 100644 docs/markdown_prefilter.py diff --git a/.github/workflows/build_documentation.yaml b/.github/workflows/build_documentation.yaml index a42b55b39..5c3180fe4 100644 --- a/.github/workflows/build_documentation.yaml +++ b/.github/workflows/build_documentation.yaml @@ -21,135 +21,12 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -env: - REBUILD_CACHE_NUMBER: 2 - PYTHON_DEPS_ARCHIVE_NUM: 2 - DOXYGEN_VERSION: Release_1_9_6 - TEX_VERSION: 2019 - # ^^ 2019 is the latest TeX live available on apt-get and that's good enough - GRAPHVIZ_VERSION: 2.43.0 - jobs: - check_menu_inclusion: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" - name: Check that all classes are documented in the menu-a-la-carte example - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - # Using answer from here to get the exit code and pass the output: https://stackoverflow.com/questions/59191913/how-do-i-get-the-output-of-a-specific-step-in-github-actions - - name: check for classes in the menu example - id: check_component - continue-on-error: true - run: | - cd $GITHUB_WORKSPACE/continuous_integration - python check_component_inclusion.py 2>&1 | tee check_component.log - result_code=${PIPESTATUS[0]} - missing_menu_docs=$(cat check_component.log) - missing_menu_docs="${missing_menu_docs//'%'/'%25'}" - missing_menu_docs="${missing_menu_docs//$'\n'/'%0A'}" - missing_menu_docs="${missing_menu_docs//$'\r'/'%0D'}" - echo "missing_menu_docs=missing_menu_docs" >> $GITHUB_OUTPUT - if [[ $result_code ]]; then - echo "$(cat check_component.log)" >> $GITHUB_STEP_SUMMARY - else - echo "Valid library.json =)" >> $GITHUB_STEP_SUMMARY - fi - echo "Finished menu inclusion verification" - exit $result_code - - - name: Create commit comment - uses: peter-evans/commit-comment@v3 - if: steps.check_component.outcome=='failure' - with: - body: | - All sensor and variable subclasses must be included in the Menu a la Carte example - ${{ steps.check_component.outputs.missing_menu_docs }} - - - name: Fail if cannot find all menu flags - id: verification_failure - if: steps.check_component.outcome=='failure' - run: exit 1 - doc_build: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" + if: ${{ ! contains(github.event.head_commit.message, 'ci skip') }} name: Build documentation - - steps: - # check out the ModularSensors repo - - uses: actions/checkout@v4 - with: - path: code_docs/ModularSensors - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Restore Python Dependencies - uses: actions/cache@v4 - id: cache_python - with: - path: ~/.cache/pip - key: ${{ runner.os }}-python-${{ env.REBUILD_CACHE_NUMBER }}-${{ env.PYTHON_DEPS_ARCHIVE_NUM }} - - - name: Install Pygments and other m.css Python Requirements - run: | - python -m pip install --upgrade pip - pip3 install --upgrade --upgrade-strategy only-if-needed jinja2 Pygments beautifulsoup4 - - - name: Restore Doxygen, Graphviz, and TeX Live - id: cache_doxygen - uses: actions/cache@v4 - with: - path: | - /usr/lib/x86_64-linux-gnu/texlive - /usr/lib/x86_64-linux-gnu/graphviz - doxygen-src - key: ${{ runner.os }}-doxygen-${{ env.REBUILD_CACHE_NUMBER }}-${{ env.DOXYGEN_VERSION }}-${{ env.TEX_VERSION }}-${{ env.GRAPHVIZ_VERSION }} - - - name: Build and install doxygen and its dependencies - if: steps.cache_doxygen.outputs.cache-hit != 'true' - run: | - cd ${{ github.workspace }}/code_docs/ModularSensors/ - chmod +x continuous_integration/build-install-doxygen.sh - sh continuous_integration/build-install-doxygen.sh - - # check out my fork of m.css, for processing Doxygen output - - name: Checkout m.css - uses: actions/checkout@v4 - with: - # Repository name with owner. For example, actions/checkout - repository: SRGDamia1/m.css - path: code_docs/m.css - - - name: Generate all the documentation - continue-on-error: true - run: | - cd ${{ github.workspace }}/code_docs/ModularSensors/ - chmod +x continuous_integration/generate-documentation.sh - sh continuous_integration/generate-documentation.sh 2>&1 | tee doxygen_run_output.log - result_code=${PIPESTATUS[0]} - echo "doxygen_warnings=$(cat docs/output_doxygen.log)" >> $GITHUB_OUTPUT - echo "mcss_warnings=$(cat docs/output_mcss.log)" >> $GITHUB_OUTPUT - echo "## Doxygen completed with the following warnings:" >> $GITHUB_STEP_SUMMARY - echo "$(cat docs/output_doxygen.log)" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "## mcss Doxygen post-processing completed with the following warnings:" >> $GITHUB_STEP_SUMMARY - echo "$(cat docs/output_mcss.log)" >> $GITHUB_STEP_SUMMARY - echo "Finished generating documentation" - exit $result_code - - - name: Deploy to github pages - if: "(github.event_name == 'release' && github.event.action == 'published') || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true')" - uses: peaceiris/actions-gh-pages@v4.0.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ${{ github.workspace }}/code_docs/ModularSensorsDoxygen/m.css + uses: EnviroDIY/workflows/.github/workflows/build_documentation.yaml@main + with: + publish: ${{ (github.event_name == 'release' && github.event.action == 'published') || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true') }} + rebuild_cache_number: 1 + secrets: inherit diff --git a/.github/workflows/build_examples.yaml b/.github/workflows/build_examples.yaml index a53fd8c0d..5f7886e53 100644 --- a/.github/workflows/build_examples.yaml +++ b/.github/workflows/build_examples.yaml @@ -8,233 +8,8 @@ concurrency: cancel-in-progress: true jobs: - generate_matrix: - name: Generate build matrices - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" - outputs: - arduino_job_matrix: ${{ steps.py_matrix.outputs.arduino_job_matrix }} - pio_job_matrix: ${{ steps.py_matrix.outputs.pio_job_matrix }} - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - cache: 'pip' - - - name: Install python dependencies, including PlatformIO - run: pip install -r continuous_integration/requirements.txt - - - name: Generate Matrices - id: py_matrix - run: | - python continuous_integration/generate_job_matrix.py - - - name: Store generated examples - uses: actions/upload-artifact@v4 - with: - name: generated_examples - path: | - continuous_integration_artifacts/ - - print_job_matrix: - name: print_job_matrix - runs-on: ubuntu-latest - needs: generate_matrix - steps: - - name: Check the generated matrix output - run: | - echo "Arduino job matrix:" - echo "${{ needs.generate_matrix.outputs.arduino_job_matrix }}" - echo - echo "PlatformIO job matrix" - echo "${{ needs.generate_matrix.outputs.pio_job_matrix }}" - - determine_library_source: - name: determine_library_source - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" - outputs: - library_install_zip: ${{ steps.store_vars.outputs.library_install_zip }} - library_install_git: ${{ steps.store_vars.outputs.library_install_git }} - - steps: - - uses: actions/checkout@v4 - - - name: Set environment variables for pushes to any branch in EnviroDIY/ModularSensors - if: github.event_name == 'push' - run: | - echo "Push to commit ${GITHUB_SHA}" - echo "LIBRARY_INSTALL_ZIP=https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.zip" >> $GITHUB_ENV - echo "LIBRARY_INSTALL_GIT=https://github.com/${GITHUB_REPOSITORY}.git#${GITHUB_SHA}" >> $GITHUB_ENV - - - name: Set environment variable for PR's from any branch in EnviroDIY/ModularSensors - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.name == github.repository - run: | - echo "Pull Request from the ${GITHUB_HEAD_REF} branch" - echo "LIBRARY_INSTALL_ZIP=https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_HEAD_REF}.zip" >> $GITHUB_ENV - echo "LIBRARY_INSTALL_GIT=https://github.com/${GITHUB_REPOSITORY}.git#${GITHUB_HEAD_REF}" >> $GITHUB_ENV - - - name: Set environment variable for PR's from any fork of ModularSensors - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.name != github.repository - run: | - echo "Pull Request from the fork ${{ github.event.pull_request.head.repo.full_name }} at ${{ github.event.pull_request.head.ref }}" - echo "LIBRARY_INSTALL_ZIP=https://github.com/${{ github.event.pull_request.head.repo.full_name }}/archive/${{ github.event.pull_request.head.ref }}.zip" >> $GITHUB_ENV - echo "LIBRARY_INSTALL_GIT=https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git#${{ github.event.pull_request.head.ref }}" >> $GITHUB_ENV - - - name: store enviroment variables as output - id: store_vars - run: | - echo "library_install_zip=${{ env.LIBRARY_INSTALL_ZIP }}" >> $GITHUB_OUTPUT - echo "library_install_git=${{ env.LIBRARY_INSTALL_GIT }}" >> $GITHUB_OUTPUT - - print_library_source: - name: print_library_source - runs-on: ubuntu-latest - needs: determine_library_source - steps: - - name: Check the library installation source - run: | - echo "Link to zip for Arduino CLI testing install:" - echo "${{ needs.determine_library_source.outputs.library_install_zip }}" - echo - echo "Git reference for PlatformIO testing install" - echo "${{ needs.determine_library_source.outputs.library_install_git }}" - - build_ex_arduino: - name: ${{ matrix.job_info.job_name }} - runs-on: ubuntu-latest - needs: [generate_matrix, determine_library_source] - env: - LIBRARY_INSTALL_ZIP: ${{ needs.determine_library_source.outputs.library_install_zip }} - strategy: - matrix: - job_info: ${{ fromJSON(needs.generate_matrix.outputs.arduino_job_matrix) }} - - steps: - - uses: actions/checkout@v4 - - - name: Unused Step - run: echo "This is needed to make the step number match with the PlatformIO jobs. =)" - - # We use the `arduino/setup-arduino-cli` action to install and - # configure the Arduino CLI on the system. - - name: Setup Arduino CLI - uses: arduino/setup-arduino-cli@v1.1.2 - - - name: Restore Arduino platforms and libraries - uses: actions/cache@v4 - id: cache_libraries - with: - path: | - home/arduino - # if nothing in the dependencies.json file has changed, then it will - # be a "cache hit" and we can restore libraries from cache and not - # download them. If it has changed we have to re-download. - key: ${{ hashFiles('./continuous_integration/dependencies.json','continuous_integration/install-deps-arduino-cli.sh') }} - - # Install cores and library dependencies for the Arduino CLI, iff no cache - - name: Install the Arduino libraries - if: steps.cache_libraries.outputs.cache-hit != 'true' - run: | - chmod +x continuous_integration/install-deps-arduino-cli.sh - sh continuous_integration/install-deps-arduino-cli.sh - - # Install ModularSensors for the Arduino CLI - - name: Install the testing version of Modular Sensors for the Arduino CLI - run: | - chmod +x continuous_integration/install-test-version-arduino-cli.sh - sh continuous_integration/install-test-version-arduino-cli.sh - - - name: Download the prepared examples - uses: actions/download-artifact@v4 - with: - name: generated_examples - path: | - continuous_integration_artifacts/ - - - name: Include problem matcher - uses: ammaraskar/gcc-problem-matcher@master - - # Run the script to compile the examples - - name: Compile - env: - ACTION_RUN_ID: ${{ github.run_id }} - run: | - chmod +x ${{ matrix.job_info.script }} - bash ${{ matrix.job_info.script }} - - # NOTE: Don't uninstall for PlatformIO because the library manager will clean up the - # dependencies leaving nothing for the cache - # pio pkg uninstall --library -g EnviroDIY_ModularSensors - - name: Uninstall testing version of Modular Sensors before caching - run: | - arduino-cli --config-file continuous_integration/arduino_cli.yaml lib uninstall ModularSensors - - build_pio: - name: ${{ matrix.job_info.job_name }} - runs-on: ubuntu-latest - needs: [generate_matrix, determine_library_source] - env: - LIBRARY_INSTALL_GIT: ${{ needs.determine_library_source.outputs.library_install_git }} - strategy: - matrix: - job_info: ${{ fromJSON(needs.generate_matrix.outputs.pio_job_matrix) }} - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - cache: 'pip' - - - name: Install python dependencies, including PlatformIO - run: pip install -r continuous_integration/requirements.txt - - - name: Restore PlatformIO platforms and libraries - uses: actions/cache@v4 - id: cache_libraries - with: - path: | - ~/.platformio - # if nothing in the dependencies.json file has changed, then it will - # be a "cache hit" and we can restore libraries from cache and not - # download them. If it has changed we have to re-download. - key: ${{ hashFiles('./continuous_integration/dependencies.json','continuous_integration/install-deps-platformio.sh') }} - - # Install the dependencies for PlatformIO - - name: Install the PlatformIO dependencies at global level - if: steps.cache_libraries.outputs.cache-hit != 'true' - run: | - chmod +x continuous_integration/install-deps-platformio.sh - sh continuous_integration/install-deps-platformio.sh - cp -a /home/runner/.platformio/lib/. $GITHUB_WORKSPACE/lib/ - - # Install ModularSensors at the Global level for PlatformIO - # Force install to get the right version - - name: Install the testing version of Modular Sensors for PlatformIO - run: | - pio pkg install -g --library ${{ env.LIBRARY_INSTALL_GIT }} - - - name: Download the prepared examples - uses: actions/download-artifact@v4 - with: - name: generated_examples - path: | - continuous_integration_artifacts/ - - - name: Include problem matcher - uses: ammaraskar/gcc-problem-matcher@master - - # Run the script to compile the examples - - name: Compile - env: - ACTION_RUN_ID: ${{ github.run_id }} - run: | - chmod +x ${{ matrix.job_info.script }} - bash ${{ matrix.job_info.script }} + build_examples: + name: Build all examples with PlatformIO and the Arduino CLI + if: ${{ ! contains(github.event.head_commit.message, 'ci skip') }} + uses: EnviroDIY/workflows/.github/workflows/build_examples.yaml@main + secrets: inherit diff --git a/.github/workflows/changelog_reminder.yaml b/.github/workflows/changelog_reminder.yaml index 90115a0cb..cf35380bb 100644 --- a/.github/workflows/changelog_reminder.yaml +++ b/.github/workflows/changelog_reminder.yaml @@ -12,7 +12,7 @@ jobs: - name: Changelog Reminder uses: peterjgrainger/action-changelog-reminder@v1.3.0 with: - changelog_regex: '/CHANGELOG\/.*\/*.md' + changelog_regex: '/CHANGELOG\/.*\/*.md/i' customPrMessage: 'Please add your changes to the change log!' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/prepare_release.yaml b/.github/workflows/prepare_release.yaml index 07f3fabe8..77f64191f 100644 --- a/.github/workflows/prepare_release.yaml +++ b/.github/workflows/prepare_release.yaml @@ -15,157 +15,9 @@ env: jobs: release: name: Prepare a new release - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set environment variable for current library version - run: | - echo "::debug::Get the current version number" - VER=$(cat VERSION) - ZIP_FILE="ModularSensors_Dependencies_${VER}" - echo "VERSION=$VER" >> $GITHUB_ENV - echo "ZIP_NAME=$ZIP_FILE" >> $GITHUB_ENV - - - name: Set up python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Install PlatformIO - run: | - python -m pip install --upgrade pip - pip install --upgrade platformio - - # Install *all* the libraries! - - name: Install the libraries - run: | - chmod +x continuous_integration/install-deps-platformio.sh - sh continuous_integration/install-deps-platformio.sh - - - name: Install ModularSensors from the master branch - run: | - pio pkg install -g -l https://github.com/EnviroDIY/ModularSensors - - # Uninstall graphics libraries from Adafruit - - name: Uninstall Adafruit GFX Library library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit GFX Library" - pio pkg uninstall -g -l "adafruit/Adafruit GFX Library" - - - name: Uninstall Adafruit NeoPixel library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit NeoPixel" - pio pkg uninstall -g -l "adafruit/Adafruit NeoPixel" - - - name: Uninstall Adafruit SSD1306 library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit SSD1306" - pio pkg uninstall -g -l "adafruit/Adafruit SSD1306" - - - name: Uninstall Adafruit ADXL343 library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit ADXL343" - pio pkg uninstall -g -l "adafruit/Adafruit ADXL343" - - - name: Uninstall Adafruit STMPE610 library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit STMPE610" - pio pkg uninstall -g -l "adafruit/Adafruit STMPE610" - - - name: Uninstall Adafruit TouchScreen library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit TouchScreen" - pio pkg uninstall -g -l "adafruit/Adafruit TouchScreen" - - - name: Uninstall Adafruit ILI9341 library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit ILI9341" - pio pkg uninstall -g -l "adafruit/Adafruit ILI9341" - - # zip up all the installed libraries - # need to cd into the pio directory so we don't get extra junk directories - - name: Zip libraries - run: | - echo "::debug::Listing global libraries" - pio pkg list -g -v --only-libraries - echo "::debug::Zipping global libraries" - cd /home/runner/.platformio/ - zip ${{ env.ZIP_NAME }}.zip -r lib - mv ${{ env.ZIP_NAME }}.zip $GITHUB_WORKSPACE - cd $GITHUB_WORKSPACE - ls - - # Remove some extras from the zip - - name: Remove git files from the zip - continue-on-error: true - run: | - echo "::debug::Deleting extra files to decrease size of zip" - echo "::debug::Removing Git folders" - zip -d -q ${{ env.ZIP_NAME }} "*/.gitattributes" "*/.gitignore" "*/.gitmodules" "*/.github/*" "*.sh" "*/Doxyfile" "*/.travis.yml" - - name: Remove other pdfs from the zip - continue-on-error: true - run: | - echo "::debug::Removing other pdfs" - zip -d -q libraries "*/doc/*.pdf" - - name: Remove TinyGSM extras from the zip - continue-on-error: true - run: | - echo "::debug::Removing TinyGSM extras" - zip -d -q libraries "*/TinyGSM/extras/*" - - name: Remove YosemitechModbus extras from the zip - continue-on-error: true - run: | - echo "::debug::Removing YosemitechModbus extras" - zip -d -q libraries "*/YosemitechModbus/doc/*" - - name: Remove SDFat extras from the zip - continue-on-error: true - run: | - echo "::debug::Removing SDFat extras" - zip -d -q libraries "*/SdFat/extras/*" - - - name: Get change log entry for release notes - id: changelog_reader - uses: mindsers/changelog-reader-action@v2 - with: - path: ChangeLog.md - version: ${{ env.VERSION }} - # validation_depth: 10 - - # I use the first line of the change log entry as the name, so read it here - # - name: Get release name - # id: get_release_name - # run: | - # release_name=$(echo ${{steps.changelog_reader.outputs.changes}} | cut -d '\n' -f 1) - # echo "release_name=release_name" >> $GITHUB_OUTPUT - - # Create a new release - - name: Create release - id: create_release - uses: softprops/action-gh-release@v2.0.5 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ format('v{0}',env.VERSION) }} - # name: ${{ format('v{0} - {1}', env.VERSION, steps.get_release_name.outputs.release_name) }} - name: ${{ format('v{0}',env.VERSION) }} - draft: ${{ steps.changelog_reader.outputs.status == 'unreleased' }} - prerelease: ${{ steps.changelog_reader.outputs.status == 'prereleased' }} - body: ${{ steps.changelog_reader.outputs.changes }} - generate_release_notes: false - files: ${{ format('./{0}.zip', env.ZIP_NAME) }} - fail_on_unmatched_files: true - - # Publish the new release to the PlatformIO package manager - - name: Publish release to the PlatformIO package manager - id: publish-pio - run: pio package publish --owner envirodiy --non-interactive + if: ${{ ! contains(github.event.head_commit.message, 'ci skip') }} + uses: EnviroDIY/workflows/.github/workflows/prepare_release.yaml@main + secrets: inherit + with: + library-manager: 'update' + library-compliance: 'specification' diff --git a/.github/workflows/verify_library_structure.yaml b/.github/workflows/verify_library_structure.yaml index 2d8aad016..9c8cbd67c 100644 --- a/.github/workflows/verify_library_structure.yaml +++ b/.github/workflows/verify_library_structure.yaml @@ -8,91 +8,11 @@ concurrency: cancel-in-progress: true jobs: - pio_lint: - name: Verify library.json for PlatformIO - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Install PlatformIO - run: | - python -m pip install --upgrade pip - pip install --upgrade platformio - - - name: Run python script to verify structure of library.json for PlatformIO - id: validate_manifest - continue-on-error: true - run: | - python continuous_integration/validate_manifest.py 2>&1 | tee validate_manifest.log - result_code=${PIPESTATUS[0]} - manifest_errors=$(cat validate_manifest.log) - manifest_errors="${manifest_errors//'%'/'%25'}" - manifest_errors="${manifest_errors//$'\n'/'%0A'}" - manifest_errors="${manifest_errors//$'\r'/'%0D'}" - echo "manifest_errors=manifest_errors" >> $GITHUB_OUTPUT - echo "$(cat validate_manifest.log)" >> $GITHUB_STEP_SUMMARY - echo "Finished library.json manifest verification" - exit $result_code - - - name: Create commit comment - uses: peter-evans/commit-comment@v3 - if: steps.validate_manifest.outcome=='failure' - with: - body: | - Please correct errors in the library.json file! - ${{ steps.validate_manifest.outputs.manifest_errors }} - - - name: Fail if cannot verify json - id: verification_failure - if: steps.validate_manifest.outcome=='failure' - run: exit 1 - - arduino_lint: - name: Validate library structure for Arduino Library Manager inclusion - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" - - steps: - - uses: actions/checkout@v4 - - - name: Run Arduino-Lint to verify the library structure and syntax for the Arduino IDE - id: validate_library - continue-on-error: true - env: - ARDUINO_LINT_LIBRARY_MANAGER_INDEXING: true - uses: arduino/arduino-lint-action@v1 - with: - project-type: library - library-manager: submit - compliance: strict - verbose: true - report-file: arduino_lint.json - - - name: beautify_lint_output - id: beautify_output - run: | - python continuous_integration/beautify_arduino_lint_log.py - lint_errors=$(cat arduino_lint.md) - lint_errors="${lint_errors//'%'/'%25'}" - lint_errors="${lint_errors//$'\n'/'%0A'}" - lint_errors="${lint_errors//$'\r'/'%0D'}" - echo "lint_errors=lint_errors" >> $GITHUB_OUTPUT - echo "$(cat arduino_lint.md)" >> $GITHUB_STEP_SUMMARY - - - name: Create commit comment - uses: peter-evans/commit-comment@v3 - if: steps.validate_library.outcome=='failure' - with: - body: ${{ steps.beautify_output.outputs.lint_errors }} - - - name: Fail if cannot verify library structure - id: verification_failure - if: steps.validate_library.outcome=='failure' - run: exit 1 + verify_library_structure: + name: Validate library structure + if: ${{ ! contains(github.event.head_commit.message, 'ci skip') }} + uses: EnviroDIY/workflows/.github/workflows/verify_library_structure.yaml@main + with: + library-manager: 'update' + library-compliance: 'specification' + # NOTE: cannot use strict for this library, because it has already been submitted with too long a name diff --git a/.gitignore b/.gitignore index b6103055d..febf07a70 100644 --- a/.gitignore +++ b/.gitignore @@ -115,3 +115,5 @@ pioScripts/install_shared_deps.py runDoxygen_archive.bat generateKeywords.bat update_path.bat +pioScripts/install_working_dependencies.py +pioScripts/target_pio_versions.py diff --git a/continuous_integration/arduino_cli.yaml b/continuous_integration/arduino_cli.yaml deleted file mode 100644 index 38376cf0d..000000000 --- a/continuous_integration/arduino_cli.yaml +++ /dev/null @@ -1,22 +0,0 @@ -board_manager: - additional_urls: - - https://raw.githubusercontent.com/EnviroDIY/Arduino_boards/master/package_EnviroDIY_index.json - - https://adafruit.github.io/arduino-board-index/package_adafruit_index.json - - http://downloads.sodaq.net/package_sodaq_samd_index.json -daemon: - port: '50051' -directories: - data: home/arduino/data - downloads: home/arduino/downloads - user: home/arduino/user -library: - enable_unsafe_install: true -logging: - file: arduino_cli.log - format: text - level: debug -metrics: - addr: :9090 - enabled: true -sketch: - always_export_binaries: false diff --git a/continuous_integration/beautify_arduino_lint_log.py b/continuous_integration/beautify_arduino_lint_log.py deleted file mode 100644 index 726f573bc..000000000 --- a/continuous_integration/beautify_arduino_lint_log.py +++ /dev/null @@ -1,42 +0,0 @@ -#%% -import json -import os - -in_json = open(os.environ["GITHUB_WORKSPACE"] + "/arduino_lint.json") -arduino_lint_results = json.load(in_json) - -out_md = open(os.environ["GITHUB_WORKSPACE"] + "/arduino_lint.md", "w+") - -out_md.write("## Results of testing examples\n\n") -out_md.write(" | Path | Project Type | Result | Problems | \n") -out_md.write(" | --- | --- | --- | --- | \n") -for project in arduino_lint_results["projects"]: - fail_list = "
    " - for failed_rule in project["rules"]: - if failed_rule["result"] != "pass": - fail_list += "
  • {}{}
      ".format( - failed_rule["ID"], - " - {}".format(failed_rule["brief"]) - if failed_rule["brief"] != "" - else "", - ) - fail_list += "
    • **{}**{}
    • ".format( - failed_rule["level"], - " - {}".format(failed_rule["message"].replace("\n", "

      ")) - if failed_rule["message"] != "" - else "", - ) - fail_list += "
  • " - fail_list += "
" - out_md.write( - " | {} | {} | {} | {} | \n".format( - project["path"] - .replace(os.environ.get("GITHUB_WORKSPACE"), "") - .replace("examples\\", ""), - project["projectType"], - ":white_check_mark:" if project["summary"]["pass"] else ":x:", - fail_list, - ) - ) - -#%% diff --git a/continuous_integration/build-install-doxygen.sh b/continuous_integration/build-install-doxygen.sh deleted file mode 100644 index f67d8cd51..000000000 --- a/continuous_integration/build-install-doxygen.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -# Makes the bash script print out every command before it is executed, except echo -trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG - -# Exit with nonzero exit code if anything fails -set -e - -# install all the dependencies for make for Doxygen and m.css -sudo apt-get update -sudo apt-get -y install build-essential -sudo apt-get -y install flex -sudo apt-get -y install bison - -# install TeX Live for LaTeX formula rendering -sudo apt-get -y install texlive-base -sudo apt-get -y install texlive-latex-extra -sudo apt-get -y install texlive-fonts-extra -sudo apt-get -y install texlive-fonts-recommended - -echo "\e[32m\n\n\nCurrent TeX version...\e[0m" -tex --version -echo "\n\n\n" - -# install Graphviz for DOT class diagrams -sudo apt-get -y install graphviz - -echo "\e[32m\n\n\nCurrent graphviz version...\e[0m" -dot -v -echo "\n\n\n" - -cd $GITHUB_WORKSPACE - -if [ ! -f $GITHUB_WORKSPACE/doxygen-src/build/bin/doxygen ]; then - - # Build instructions from: https://www.stack.nl/~dimitri/doxygen/download.html - echo "\e[32mCloning doxygen repository...\e[0m" - git clone https://github.com/doxygen/doxygen.git doxygen-src --branch $DOXYGEN_VERSION --depth 1 - - cd doxygen-src - - echo "\e[32mCreate build folder...\e[0m" - mkdir build - cd build - - echo "\e[32mMake...\e[0m" - cmake -G "Unix Makefiles" .. - make - echo "\e[32mDone building doxygen.\e[0m" - echo "\e[32mdoxygen path: \e[0m" $(pwd) -fi - -echo "\e[32m\n\n\nCurrent Doxygen version...\e[0m" -$GITHUB_WORKSPACE/doxygen-src/build/bin/doxygen -v -echo "\n\n\n" - -# echo "\e[32mMove Doxygen to working directory" -# cp $GITHUB_WORKSPACE/doxygen-src/build/bin/* $GITHUB_WORKSPACE/code_docs/ModularSensors -# #make install - -cd $GITHUB_WORKSPACE/code_docs/ModularSensors diff --git a/continuous_integration/copy-doc-sources.sh b/continuous_integration/copy-doc-sources.sh deleted file mode 100644 index 67acbc003..000000000 --- a/continuous_integration/copy-doc-sources.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -# Makes the bash script print out every command before it is executed, except echo -trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG - -# Script modified from scripts by Jeroen de Bruijn, thephez, and Adafruit -# https://gist.github.com/vidavidorra/548ffbcdae99d752da02 -# https://github.com/thephez/doxygen-travis-build -# https://learn.adafruit.com/the-well-automated-arduino-library/travis-ci - -# Exit with nonzero exit code if anything fails -set -e - -# Create a clean working directory for this script. -mkdir $GITHUB_WORKSPACE/code_docs -cd $GITHUB_WORKSPACE/code_docs - -# Re-clone the main repo, not sparsely -git clone -b master --depth 1 https://github.com/EnviroDIY/ModularSensors ModularSensors - -# Clone the wiki, because we'll be using it in the docs -git clone --depth 1 https://github.com/EnviroDIY/ModularSensors.wiki - -# Clone m.css for its theming -git clone --depth 1 https://github.com/SRGDamia1/m.css m.css - -# Get the current gh-pages branch -# git clone -b gh-pages https://git@$GH_REPO_REF -# cd $GH_REPO_NAME -git clone -b gh-pages --depth 1 https://github.com/EnviroDIY/ModularSensors ModularSensorsDoxygen -cd ModularSensorsDoxygen -echo "Documentation path: " $(pwd) - -# Remove everything currently in the gh-pages branch. -# GitHub is smart enough to know which files have changed and which files have -# stayed the same and will only update the changed files. So the gh-pages branch -# can be safely cleaned, and it is sure that everything pushed later is the new -# documentation. -rm -rf * - -# Need to create a .nojekyll file to allow filenames starting with an underscore -# to be seen on the gh-pages site. Therefore creating an empty .nojekyll file. -# Presumably this is only needed when the SHORT_NAMES option in Doxygen is set -# to NO, which it is by default. So creating the file just in case. -echo "" > .nojekyll -ls diff --git a/continuous_integration/generate-documentation.sh b/continuous_integration/generate-documentation.sh deleted file mode 100644 index 5985eeaa1..000000000 --- a/continuous_integration/generate-documentation.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -# Makes the bash script print out every command before it is executed, except echo -trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG - -# Script modified from scripts by Jeroen de Bruijn, thephez, and Adafruit -# https://gist.github.com/vidavidorra/548ffbcdae99d752da02 -# https://github.com/thephez/doxygen-travis-build -# https://learn.adafruit.com/the-well-automated-arduino-library/travis-ci - -# Exit with nonzero exit code if anything fails -set -e - -cd $GITHUB_WORKSPACE/code_docs/m.css -echo "\n\e[32mUpdate the style sheets\e[0m" -cd $GITHUB_WORKSPACE/code_docs/m.css/css/EnviroDIY -python $GITHUB_WORKSPACE/code_docs/m.css/css/postprocess.py "m-EnviroDIY.css" -python $GITHUB_WORKSPACE/code_docs/m.css/css/postprocess.py "m-EnviroDIY.css" "m-documentation.css" -o "m-EnviroDIY+documentation.compiled.css" -python $GITHUB_WORKSPACE/code_docs/m.css/css/postprocess.py "m-EnviroDIY.css" "m-theme-EnviroDIY.css" "m-documentation.css" --no-import -o "m-EnviroDIY.documentation.compiled.css" -cp $GITHUB_WORKSPACE/code_docs/m.css/css/EnviroDIY/m-EnviroDIY+documentation.compiled.css $GITHUB_WORKSPACE/code_docs/ModularSensors/docs/css - -cd $GITHUB_WORKSPACE/code_docs/ModularSensors/docs - -# echo "\n\e[32mCreating dox files from example read-me files\e[0m" -# python documentExamples.py - -echo "\n\e[32mCurrent Doxygen version...\e[0m" -$GITHUB_WORKSPACE/doxygen-src/build/bin/doxygen -v 2>&1 - -# Redirect both stderr and stdout to the log file AND the console. -echo "\n\e[32mGenerating Doxygen code documentation...\e[0m" -$GITHUB_WORKSPACE/doxygen-src/build/bin/doxygen Doxyfile 2>&1 - -echo "\n\e[32mFixing errant xml section names in examples as generated by Doxygen...\e[0m" -python fixSectionsInXml.py - -# echo "\n\e[32mFixing copied function documentation in group documentation\e[0m" -# python fixFunctionsInGroups.py - -python $GITHUB_WORKSPACE/code_docs/m.css/documentation/doxygen.py "mcss-conf.py" --no-doxygen --output "$GITHUB_WORKSPACE/code_docs/ModularSensors/docs/output_mcss.log" --templates "$GITHUB_WORKSPACE/code_docs/m.css/documentation/templates/EnviroDIY" - -echo "\n\e[32mCopying function documentation\e[0m" -python copyFunctions.py diff --git a/continuous_integration/install-test-version-arduino-cli.sh b/continuous_integration/install-test-version-arduino-cli.sh deleted file mode 100644 index 74ac0f883..000000000 --- a/continuous_integration/install-test-version-arduino-cli.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -# Makes the bash script print out every command before it is executed, except echo -trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG - -# Exit with nonzero exit code if anything fails -set -e - -echo "\n\e[32mCurrent Arduino CLI version:\e[0m" -arduino-cli version - -echo "\n\e[32mDeleting any archived zips\e[0m" -rm -f home/arduino/downloads/ModularSensors.zip - -echo "\n\e[32mDownloading library zip from ${LIBRARY_INSTALL_ZIP}\e[0m" -curl -L --retry 15 --retry-delay 0 ${LIBRARY_INSTALL_ZIP} --create-dirs -o home/arduino/downloads/ModularSensors.zip - -echo "\n\e[32mUnzipping the library\e[0m" -unzip -o home/arduino/downloads/ModularSensors.zip -d home/arduino/downloads/ -x "*.git/*" "continuous_integration/*" "docs/*" "examples/*" - -echo "\n\e[32mEnsuring no old directories exist\e[0m" -rm -r -f home/arduino/user/libraries/ModularSensors - -echo "\n\e[32mCreating a new directory for the testing version of Modular sensors\e[0m" -mkdir -p home/arduino/user/libraries/ModularSensors - -echo "\n\e[32mMoving the unzipped library to the new directory\e[0m" -if [ -z "${GITHUB_HEAD_REF}" ]; then - echo "\n\e[36mExpected unzipped directory name (from commit SHA): home/arduino/downloads/ModularSensors-${GITHUB_SHA}\e[0m" - mv home/arduino/downloads/ModularSensors-${GITHUB_SHA}/* home/arduino/user/libraries/ModularSensors -else - INTERNAL_ZIP_NAME=$(echo "${GITHUB_HEAD_REF}" | sed -e 's/\//-/g') - echo "\n\e[36mExpected unzipped directory name (from head of ${GITHUB_HEAD_REF}): home/arduino/downloads/ModularSensors-${SAVED_ZIP_NAME}\e[0m" - mv home/arduino/downloads/ModularSensors-${INTERNAL_ZIP_NAME}/* home/arduino/user/libraries/ModularSensors -fi - -echo "\n\e[32mUpdating the library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib update-index - -echo "\n\e[32mListing libraries detected by the Arduino CLI\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib list - -echo "\n\e[32mListing the contents of the Arduino library directory\e[0m" -ls home/arduino/user/libraries diff --git a/continuous_integration/requirements.txt b/continuous_integration/requirements.txt deleted file mode 100644 index 31e6105b7..000000000 --- a/continuous_integration/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -# Wheel for installs -wheel - -# use platformio for all of the compiler testing -platformio diff --git a/continuous_integration/validate_manifest.py b/continuous_integration/validate_manifest.py deleted file mode 100644 index 124a4875d..000000000 --- a/continuous_integration/validate_manifest.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2014-present PlatformIO -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from platformio.package.manifest.parser import ManifestParserFactory -from platformio.package.manifest.schema import ManifestSchema - -mp = ManifestParserFactory.new_from_file("library.json") -parsed = ManifestSchema().load_manifest(mp.as_dict()) diff --git a/docs/copyFunctions.py b/docs/copyFunctions.py deleted file mode 100644 index 3e0c64f56..000000000 --- a/docs/copyFunctions.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python -import fileinput -import re -import os -import glob -import xml.etree.ElementTree as ET -from html.parser import HTMLParser -from bs4 import BeautifulSoup - -fileDir = os.path.dirname(os.path.realpath("__file__")) -# print("Program Directory: {}".format(fileDir)) -relative_dir = "../../ModularSensorsDoxygen/m.css/" -abs_file_path = os.path.join(fileDir, relative_dir) -abs_file_path = os.path.abspath(os.path.realpath(abs_file_path)) -# print("XML Directory: {}".format(fileDir)) - -all_files = [ - f - for f in os.listdir(abs_file_path) - if os.path.isfile(os.path.join(abs_file_path, f)) - and f.endswith(".html") - and not f.endswith("fixed") -] - - -def get_section_to_paste(match: re.Match) -> str: - source_file = match.group("copy_source_file") - # print(source_file) - source_section = match.group("copy_section_id") - # print(source_section) - with open(os.path.join(abs_file_path, source_file), encoding="utf8") as fp: - soup = BeautifulSoup(fp, "html.parser") - details = soup.find(id=source_section) - # print("Details:", details, "\n\n") - link = details.find("a", class_="m-doc-self") - # print("Link:", link, "\n\n") - link["href"] = source_file + "#" + source_section - # print("Link:", link, "\n\n") - # print("Details:", details, "\n\n") - return str(details) - - # tree = ET.parse() - # root = tree.getroot() - - # for definition in root.iter("compounddef"): - # # print(definition.attrib) - # compound_id = definition.attrib["id"] - # # print(compound_id) - # # print("---") - - -# {{ AOSongAM2315_Humidity::AOSongAM2315_Humidity }} -files_to_copy_to = [] -for filename in all_files: - abs_in = os.path.join(abs_file_path, filename) - abs_out = os.path.join(abs_file_path, filename + "_fixed") - copy_paste_needed = False - # with open(os.path.join(abs_file_path, filename)) as fp: - # soup = BeautifulSoup(fp, "html.parser") - # for find in soup.find_all(string=[re.compile("\{\{")]): - # print(find.find_parent("p").a.get("href")) - - with open(abs_in, "r", encoding="utf8") as in_file: # open in readonly mode - lines = in_file.readlines() - i = 0 - new_lines = [] - for line in lines: - i += 1 - new_line = line - match = re.search( - r'{{ ") - new_line = new_line.replace("</span>", "") - new_line = new_line.replace( - "mcss:class="m-dim">", 'mcss:class="m-dim">' - ) - new_line = new_line.replace( - "class="m-dim">", 'class="m-dim">' - ) - new_line = new_line.replace( - "mcss:class="m-param">", 'mcss:class="m-param">' - ) - new_line = new_line.replace( - "class="m-param">", 'class="m-param">' - ) - new_line = new_line.replace( - "mcss:class="m-doc-wrap">", 'mcss:class="m-doc-wrap">' - ) - new_line = new_line.replace( - "class="m-doc-wrap">", 'class="m-doc-wrap">' - ) - new_line = new_line.replace("<span", "', - '\nParameters', - ) - new_line = new_line.replace("", "
") - - new_line = new_line.replace("", "") - new_line = new_line.replace("", "") - - new_line = new_line.replace("\n", "") - new_line = new_line.replace("\n", "") - - new_line = new_line.replace( - "", - '', - ) - new_line = new_line.replace("", "") - - new_line = new_line.replace( - "", '' - ) - new_line = new_line.replace("", "") - - out_file.write(new_line) - - os.rename( - os.path.join(abs_file_path, filename), - os.path.join(abs_file_path, filename + "_original"), - ) - os.rename( - os.path.join(abs_file_path, filename + "_fixed"), - os.path.join(abs_file_path, filename), - ) diff --git a/docs/fixSectionsInXml.py b/docs/fixSectionsInXml.py deleted file mode 100644 index 682c64b89..000000000 --- a/docs/fixSectionsInXml.py +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/env python -#%% -import fileinput -import re -import os -import glob -import xml.etree.ElementTree as ET - -fileDir = os.path.dirname(os.path.realpath("__file__")) -# print("Program Directory: {}".format(fileDir)) -relative_dir = "../../ModularSensorsDoxygen/xml/" -abs_file_path = os.path.join(fileDir, relative_dir) -abs_file_path = os.path.abspath(os.path.realpath(abs_file_path)) -# print("XML Directory: {}".format(fileDir)) - -all_files = [ - f - for f in os.listdir(abs_file_path) - if os.path.isfile( - os.path.join(abs_file_path, f) - ) # and f.endswith("8ino-example.xml") -] - -compound_def = r".+?)\" kind=\"\w+?\">" -section_header = r"[123456]) id=\"(?P.+)\">" -doxy_file_location = r".+)\"/>" -#%% -for filename in all_files: - # print("Now on {}".format(os.path.join(abs_file_path, filename))) - - needs_to_be_fixed = False - - doxygen_compound_id = None - section_number = None - doxygen_sect_id = None - sections_to_fix = [] - # First search the xml for the location of the original file. - # This will be at the end of the xml, so we need to find this, close the file, - # and then reopen to search for the compound def and section. - original_xml = open( - os.path.join(abs_file_path, filename), mode="r", encoding="utf-8" - ) - # filetext = original_xml.read() - for line in original_xml.readlines(): - if re.search(doxy_file_location, line) is not None: - file_location = re.search(doxy_file_location, line).group("file_location") - original_xml.close() - - # Now search for the sections - original_xml = open( - os.path.join(abs_file_path, filename), mode="r", encoding="utf-8" - ) - for line in original_xml.readlines(): - # print(line, end="") - if re.search(compound_def, line) is not None: - doxygen_compound_id = re.search(compound_def, line).group( - "doxygen_compound_id" - ) - if re.search(section_header, line) is not None: - section_number = re.search(section_header, line).group("section_number") - doxygen_sect_id = re.search(section_header, line).group("doxygen_sect_id") - # print( - # "section_number:", section_number, "doxygen_sect_id:", doxygen_sect_id - # ) - if ( - not doxygen_sect_id.startswith(doxygen_compound_id) - and file_location in doxygen_sect_id - ): - needs_to_be_fixed = True - file_name_loc = doxygen_sect_id.find(file_location) - section_suffix = doxygen_sect_id[ - file_name_loc + len(file_location) + 2 : - ] - corrected_id = doxygen_compound_id + "_" + section_suffix - sections_to_fix.append( - { - "doxygen_compound_id": doxygen_compound_id, - "section_number": section_number, - "doxygen_sect_id": doxygen_sect_id, - "file_location": file_location, - "needs_to_be_fixed": True, - "corrected_id": corrected_id, - } - ) - print( - "Will correct:\n\t{}\nTo:\n\t{}".format( - doxygen_sect_id, corrected_id - ) - ) - - original_xml.close() - - # Now we're going to open the file and copy to a new one with corrections applied - if needs_to_be_fixed: - original_xml = open( - os.path.join(abs_file_path, filename), mode="r", encoding="utf-8" - ) - corrected_xml = open( - os.path.join(abs_file_path, filename + "_fixed"), mode="w", encoding="utf-8" - ) - for line in original_xml.readlines(): - corrected_line = line - for section_to_fix in sections_to_fix: - corrected_line = re.sub( - r"[123456]) id=\"" - + section_to_fix["doxygen_sect_id"] - + r"\">", - r' id="' - + section_to_fix["corrected_id"] - + r'">', - corrected_line, - ) - # corrected_line = corrected_line.replace( - # ' id="{}"'.format(section_to_fix["doxygen_sect_id"]), - # ' id="{}"'.format(section_to_fix["corrected_id"]), - # ) - corrected_xml.write(corrected_line) - original_xml.close() - corrected_xml.close() - - if needs_to_be_fixed: - os.rename( - os.path.join(abs_file_path, filename), - os.path.join(abs_file_path, filename + "_original"), - ) - os.rename( - os.path.join(abs_file_path, filename + "_fixed"), - os.path.join(abs_file_path, filename), - ) - print("Saved changed file") - print("-----\n\n\n") - # else: - # print("No changes needed") - # print("-----\n") - # break - -# %% diff --git a/docs/markdown_prefilter.py b/docs/markdown_prefilter.py deleted file mode 100644 index 2ab05e26f..000000000 --- a/docs/markdown_prefilter.py +++ /dev/null @@ -1,355 +0,0 @@ -#!/usr/bin/env python -#%% -import enum -import fileinput -import re -import sys -import string - -# a helper function to go from snake back to camel -def snake_to_camel(snake_str): - components = snake_str.strip().split("_") - # We capitalize the first letter of each component except the first one - # with the 'title' method and join them together. - camel_str = components[0] + "".join(x.title() for x in components[1:]) - if camel_str.startswith("_"): - return camel_str[1:] - else: - return camel_str - - -def camel_to_snake(name): - name = name.strip().replace(" ", "_") - name = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name.strip()) - return re.sub("([a-z0-9])([A-Z])", r"\1_\2", name).lower() - - -def github_slugify(name): - return ( - name.strip() - .lower() - .replace( - "-", " " - ) # convert dashes to spaces so they don't get lost with other punctuation - .translate(str.maketrans("", "", string.punctuation)) - .replace(" ", " ") - .replace(" ", " ") - .replace(" ", "-") - ) - - -# Add a start comment to make the entire markdown file function as a comment block -# Without this doxygen sometimes recognizes its own special commands, but mostly doesn't -# Not needed anymore with doxygen 1.9.3? -# try: -# sys.stdout.buffer.write("\n/**\n".encode("utf-8")) -# except Exception as e: -# print("\n*/\n\n") - -#%% -print_me = True -skip_me = False -i = 1 - -# when testing use: -# with fileinput.FileInput("..\\ChangeLog.md", -# openhook=fileinput.hook_encoded("utf-8", "surrogateescape") -# ) as input: - -with fileinput.FileInput( - openhook=fileinput.hook_encoded("utf-8", "surrogateescape") -) as input: - for line in input: - if input.isfirstline(): - # Get the file name and directory - # We'll use this to create the section id comment - file_name_dir = input.filename() - if "\\" in file_name_dir: - seper = "\\" - else: - seper = "/" - # sys.stdout.buffer.write("Separator: '{}'\n".format(seper).encode("utf-8")) - file_dir = file_name_dir.rsplit(sep=seper, maxsplit=1)[0] - file_name_ext = file_name_dir.rsplit(sep=seper, maxsplit=1)[1] - file_name = file_name_ext.rsplit(sep=".", maxsplit=1)[0] - file_ext = file_name_ext.rsplit(sep=".", maxsplit=1)[1] - # sys.stdout.buffer.write( - # "File Directory: {}, File Name: {}, File Extension: {}\n".format( - # file_dir, file_name, file_ext - # ).encode("utf-8") - # ) - # For the example walk-throughs, written in the ReadMe files, - # we want the example name, which is part of the directory. - if "examples" in file_dir and file_name == "ReadMe": - file_name = "example_" + file_dir.rsplit(sep=seper, maxsplit=1)[-1] - - # print(i, print_me, skip_me, line) - - # I'm using these comments to fence off content that is only intended for - # github mardown rendering - if "[//]: # ( Start GitHub Only )" in line: - print_me = False - - # copy the original line to work with - massaged_line = line - # Convert markdown comment tags to c++/dox style comment tags - massaged_line = re.sub(r"\[//\]: # \( @(\w+?.*) \)", r"@\1", massaged_line) - # allow thank you tags - massaged_line = massaged_line.replace("thanks to @", r"thanks to \@") - - # Convert GitHub pages url's to refs - # I'm putting the long URL in the markdown because I want the links there to - # work and go to the pages. But when feeding it to Doxygen, I want them to be - # ref's so Doxygen will both check the existence of the refs and create new - # links for them. - - # For links to sections, doxygen cuts off the first letter of the section name - # in the examples (UGH), so some acrobatics to find them - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/[\w/-]+\.html#enu_walk_(?P[\w/-]+)", - r"@ref menu_walk_\g", - massaged_line, - ) - # for classes, we need to switch camel and snake cases - class_link = re.search( - r"https://envirodiy.github.io/ModularSensors/(?:class)(?P[\w/-]+)\.html", - massaged_line, - ) - if class_link is not None: - camel_link = snake_to_camel(class_link.group("class_link")) - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/(?:class)(?P[\w/-]+)\.html", - r"@ref #" + camel_link, - massaged_line, - ) - # for groups, we need to clean out extra underscores - group_link = re.search( - r"https://envirodiy.github.io/ModularSensors/(?:group__)(?P[\w/-]+)\.html", - massaged_line, - ) - if group_link is not None: - camel_link = group_link.group("group_link").replace("__", "_") - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/(?:group__)(?P[\w/-]+)\.html", - r"@ref #" + camel_link, - massaged_line, - ) - # for examples, we need to clean out extra underscores - example_link = re.search( - r"https://envirodiy.github.io/ModularSensors/(?P[\w/-]+)_8ino-example\.html", - massaged_line, - ) - if example_link is not None: - camel_link = snake_to_camel(example_link.group("example_name")) - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/(?P[\w/-]+)_8ino-example\.html", - "@ref " + snake_to_camel(example_link.group("example_name")) + ".ino", - massaged_line, - ) - - # If it's the index itself, we want to replace with a reference to the mainpage - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/index.html#(?P[\w/-]+)", - r"@ref \g", - massaged_line, - ) - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/index.html", - "@ref mainpage", - massaged_line, - ) - - # for anything other link to the docs, we the text as it is and hope it - # lines up with a real reference - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/(?P[\w/-]+)\.html", - r"@ref \g", - massaged_line, - ) - - # Add a PHP Markdown Extra style header id to the end of header sections - # use the GitHub anchor plus the file name as the section id. - # GitHub anchors for headers are the text, stripped of punctuation, - # with the spaces replaced by hyphens. - markdown_header = re.match( - r"(?P#{1,6})\s+(?P[^<>\{\}\#]+)", - massaged_line, - ) - php_extra_header_label = re.search(r"\{#(.+)\}", massaged_line) - anchor_header = re.search( - r"
\w+)\">", massaged_line - ) - if ( - file_name is not None - and file_name != "ChangeLog" - and markdown_header is not None - and php_extra_header_label is None - and anchor_header is None - ): - massaged_line = ( - markdown_header.group("heading_pounds") - + " " - + markdown_header.group("section_name").strip() - + " {#" - + camel_to_snake(file_name) - + "_" - + github_slugify(markdown_header.group("section_name")) - + "}\n" - ) - - elif ( - file_name is not None - and file_name != "ChangeLog" - and markdown_header is not None - and php_extra_header_label is not None - ): - # unhide PHP Markdown Extra header id's hidding in GitHub flavored markdown comments - massaged_line = re.sub(r"", r"{#\1}", massaged_line,) - # if input.isfirstline(): - # else: - # massaged_line = ( - # markdown_header.group("heading_pounds") - # + " " - # + markdown_header.group("section_name").strip() - # + " {#" - # + camel_to_snake(file_name) - # + "_" - # + github_slugify(markdown_header.group("section_name")) - # + "}\n" - # ) - - elif ( - file_name is not None - and file_name != "ChangeLog" - and markdown_header is not None - and anchor_header is not None - ): - # convert anchors to section names - massaged_line = re.sub( - r"\w+)\">", - r"{#\g}", - massaged_line, - ) - - # Special work-arounds for the change log - if file_name is not None and file_name == "ChangeLog": - if line.startswith("# ChangeLog"): - massaged_line = "# ChangeLog {#change_log}\n" - version_re = re.match( - r"#{2}\s+(?P\[(?P[^\{\}\#]+?)\])(?P.*)", - massaged_line, - ) - version_action_re = re.match( - r"#{3}\s+(?P(?:Changed)|(?:Added)|(?:Removed)|(?:Fixed)|(?:Known Issues))", - massaged_line, - ) - if version_re is not None: - change_log_version = ( - version_re.group("version_number").strip().lower().replace(".", "-") - ) - change_log_link = version_re.group("changelog_link") - massaged_line = ( - "@section " - + camel_to_snake(file_name) - + "_" - + change_log_version - + " " - + version_re.group("version_number") - + version_re.group("version_info") - + "\n" - + "GitHub Release: " - + change_log_link - # + "\n" #NOTE: Adding the new line here would offset all doxygen line numbers - ) - if version_action_re is not None: - massaged_line = ( - massaged_line.rstrip() - + " {#" - + camel_to_snake(file_name) - + "_" - + change_log_version - + "_" - + camel_to_snake(version_action_re.group("section_name")) - + "}\n" - ) - - # convert internal hash-tag links to reference links - internal_hash_link = re.search( - r"\]\(#(?P[\w/-]+)\)", massaged_line, - ) - if internal_hash_link is not None: - massaged_line = re.sub( - r"\]\(#(?P[\w/-]+)\)", - "](@ref " - + camel_to_snake(file_name) - + "_" - + github_slugify(internal_hash_link.group("internal_anchor")) - + ")", - massaged_line, - ) - - # finally replace code blocks with doxygen's prefered code block - massaged_line = ( - massaged_line.replace("```ini", "@code{.ini}") - .replace("```cpp", "@code{.cpp}") - .replace("```", "@endcode") - ) - - # hide lines that are not printed or skipped - # write out an empty comment line to keep the line numbers identical - if skip_me or not print_me: - massaged_line = "\n" - - if ( - massaged_line.count("\n") != line.count("\n") - or line.count("\n") != 1 - or massaged_line.count("\n") != 1 - ): - raise Exception( - '\n\nNot exactly one new lines\nFile:{}\nLine Number:{}\nNew Lines in Original: {}\nOriginal Line:\n"{}"\nNew Lines after Massage: {}\nMassaged Line:\n"{}"\n\n'.format( - input.filename(), - input.filelineno(), - line.count("\n"), - line, - massaged_line.count("\n"), - massaged_line, - ) - ) - - # write out the result - try: - sys.stdout.buffer.write(massaged_line.encode("utf-8")) - except Exception as e: - print(massaged_line, end="") - - # using skip_me to skip single lines, so unset it after reading a line - if skip_me: - skip_me = False - - # a page, section, subsection, or subsubsection commands followed - # immediately with by a markdown header leads to that section appearing - # twice in the doxygen html table of contents. - # I'm putting the section markers right above the header and then will skip the header. - if re.match(r"\[//\]: # \( @mainpage", line) is not None: - skip_me = True - if re.match(r"\[//\]: # \( @page", line) is not None: - skip_me = True - if re.match(r"\[//\]: # \( @.*section", line) is not None: - skip_me = True - if re.match(r"\[//\]: # \( @paragraph", line) is not None: - skip_me = True - - # I'm using these comments to fence off content that is only intended for - # github mardown rendering - if "[//]: # ( End GitHub Only )" in line: - print_me = True - - i += 1 - -#%% -# Close the comment for doxygen -# Not needed anymore with doxygen 1.9.3? -# try: -# sys.stdout.buffer.write("\n*/\n\n".encode("utf-8")) -# except Exception as e: -# print("\n*/\n\n") From c6e2688c69159adb13798af9b9b91834793049da Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 11 Jun 2024 16:51:31 -0400 Subject: [PATCH 075/138] Fix library structure compliance Signed-off-by: Sara Damiano --- .github/workflows/verify_library_structure.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/verify_library_structure.yaml b/.github/workflows/verify_library_structure.yaml index 9c8cbd67c..9c72b21cf 100644 --- a/.github/workflows/verify_library_structure.yaml +++ b/.github/workflows/verify_library_structure.yaml @@ -13,6 +13,5 @@ jobs: if: ${{ ! contains(github.event.head_commit.message, 'ci skip') }} uses: EnviroDIY/workflows/.github/workflows/verify_library_structure.yaml@main with: - library-manager: 'update' - library-compliance: 'specification' - # NOTE: cannot use strict for this library, because it has already been submitted with too long a name + library-manager: 'submit' + library-compliance: 'strict' From 338a78591ca8bafc3ab65410641fad6ec124625a Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 12 Jun 2024 13:52:47 -0400 Subject: [PATCH 076/138] Reorder defines Signed-off-by: Sara Damiano --- .gitignore | 9 +-- docs/Doxyfile | 2 +- src/sensors/AnalogElecConductivity.h | 82 +++++++++++++++------------- src/sensors/ApogeeSQ212.h | 18 +++--- 4 files changed, 54 insertions(+), 57 deletions(-) diff --git a/.gitignore b/.gitignore index febf07a70..de92a0101 100644 --- a/.gitignore +++ b/.gitignore @@ -88,13 +88,7 @@ docs/examples.dox_x platformio_extra_envs.ini src/sensors/table.md cache -output_doxygen.log -output_doxygen_run.log -output_mcss_run.log -output_mcss.log -docs/output_copyFunctions.log -docs/output_documentExamples.log -docs/output_fixSectionsInXml.log +output_*.log examples/DRWI_Mayfly1_Wifi_5tm_ds18b20_1/DRWI_Mayfly1_Wifi_5tm_ds18b20_1.ino clang_format_all.bat arduino_lint.md @@ -109,7 +103,6 @@ continuous_integration_artifacts/* arduino_cli.log **/sensor_tests/* docs/Doxyfile.bak -continuous_integration/output_check_component_inclusion.log continuous_integration/platformio_ci_local.ini pioScripts/install_shared_deps.py runDoxygen_archive.bat diff --git a/docs/Doxyfile b/docs/Doxyfile index ee2146abb..2d8ef48b5 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -547,7 +547,7 @@ EXTRACT_ALL = NO # be included in the documentation. # The default value is: NO. -EXTRACT_PRIVATE = YES +EXTRACT_PRIVATE = NO # If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual # methods of a class will be included in the documentation. diff --git a/src/sensors/AnalogElecConductivity.h b/src/sensors/AnalogElecConductivity.h index 19bba3a36..a0cb40c79 100644 --- a/src/sensors/AnalogElecConductivity.h +++ b/src/sensors/AnalogElecConductivity.h @@ -139,12 +139,13 @@ #ifdef MS_ANALOGELECCONDUCTIVITY_DEBUG_DEEP #define MS_DEBUGGING_DEEP "AnalogElecConductivity" #endif + // Included Dependencies #include "ModSensorDebugger.h" #undef MS_DEBUGGING_STD #undef MS_DEBUGGING_DEEP -#include "SensorBase.h" #include "VariableBase.h" +#include "SensorBase.h" #include "math.h" /** @ingroup sensor_analog_cond */ @@ -154,7 +155,7 @@ /// @brief Sensor::_numReturnedValues; we only get one value from the analog /// conductivity sensor. #define ANALOGELECCONDUCTIVITY_NUM_VARIABLES 1 -/// @brief Sensor::_incCalcValues; we don't calculate any additional values - +/// @brief Sensor::_incCalcValues; we don't calculate any additional values /// though we recommend users include a temperature sensor and calculate /// specific conductance in their own program. #define ANALOGELECCONDUCTIVITY_INC_CALC_VARIABLES 0 @@ -183,39 +184,13 @@ #define ANALOGELECCONDUCTIVITY_MEASUREMENT_TIME_MS 0 /**@}*/ - /** - * @anchor sensor_analog_cond_parts_ec - * @name Electrical Conductance - * The humidity variable from an AOSong DHT - * - Range: low 100's when open air, for short circuit: a high number - * - Accuracy: needs determining for each combination of ADC. ADC_REF, and - * series R. its designed as a very simple relative EC measurement - * - * {{ @ref AnalogElecConductivity_EC::AnalogElecConductivity_EC }} + * @anchor sensor_analog_cond_parts_config + * @name Configuration Defines + * Defines to help configure the outputs from the home-made conductivity sensor. */ /**@{*/ -/** - * @brief Decimals places in string representation; EC should have 1 - * - * Range of 0-3V3 with 10bit ADC - resolution of 0.003 = 3 µS/cm. - */ -#define ANALOGELECCONDUCTIVITY_EC_RESOLUTION 1 -/// @brief Sensor vensor variable number; EC is stored in sensorValues[0]. -#define ANALOGELECCONDUCTIVITY_EC_VAR_NUM 0 -/// @brief Variable name in -/// [ODM2 controlled vocabulary](http://vocabulary.odm2.org/variablename/); -/// "electricalConductivity" -#define ANALOGELECCONDUCTIVITY_EC_VAR_NAME "electricalConductivity" -/// @brief Variable unit name in -/// [ODM2 controlled vocabulary](http://vocabulary.odm2.org/units/); -/// "microsiemenPerCentimeter" (µS/cm) -#define ANALOGELECCONDUCTIVITY_EC_UNIT_NAME "microsiemenPerCentimeter" -/// @brief Default variable short code; "anlgEc" -#define ANALOGELECCONDUCTIVITY_EC_DEFAULT_CODE "anlgEc" -/**@}*/ - -#if !defined ANALOG_EC_ADC_RESOLUTION +#if !defined ANALOG_EC_ADC_RESOLUTION || defined(DOXYGEN) /** * @brief Default resolution (in bits) of the voltage measurement * @@ -232,7 +207,7 @@ #define ANALOG_EC_ADC_RANGE (1 << ANALOG_EC_ADC_RESOLUTION) /* clang-format off */ -#if !defined ANALOG_EC_ADC_REFERENCE_MODE +#if !defined ANALOG_EC_ADC_REFERENCE_MODE || defined (DOXYGEN) #if defined (ARDUINO_ARCH_AVR) || defined (DOXYGEN) /** * @brief The voltage reference mode for the processor's ADC. @@ -282,7 +257,7 @@ #endif // ARDUINO_ARCH_SAMD /* clang-format on */ -#if !defined RSERIES_OHMS_DEF +#if !defined RSERIES_OHMS_DEF || defined(DOXYGEN) /** * @brief The default resistance (in ohms) of the measuring resistor. * This should not be less than 300 ohms when measuring EC in water. @@ -290,7 +265,7 @@ #define RSERIES_OHMS_DEF 499 #endif // RSERIES_OHMS_DEF -#if !defined SENSOREC_KONST_DEF +#if !defined SENSOREC_KONST_DEF || defined(DOXYGEN) /** * @brief Cell Constant For EC Measurements. * @@ -304,9 +279,39 @@ */ #define SENSOREC_KONST_DEF 1.0 #endif // SENSOREC_KONST_DEF +/**@}*/ + +/** + * @anchor sensor_analog_cond_parts_ec + * @name Electrical Conductance + * The electrical conductance variable from a home-made analog sensor. + * + * {{ @ref AnalogElecConductivity_EC::AnalogElecConductivity_EC }} + */ +/**@{*/ +/** + * @brief Decimals places in string representation; EC should have 1 + * + * Range of 0-3V3 with 10bit ADC - resolution of 0.003 = 3 µS/cm. + */ +#define ANALOGELECCONDUCTIVITY_EC_RESOLUTION 1 +/// @brief Sensor variable number; EC is stored in sensorValues[0]. +#define ANALOGELECCONDUCTIVITY_EC_VAR_NUM 0 +/// @brief Variable name in [ODM2 controlled +/// vocabulary](http://vocabulary.odm2.org/variablename/); +/// "electricalConductivity" +#define ANALOGELECCONDUCTIVITY_EC_VAR_NAME "electricalConductivity" +/// @brief Variable unit name in +/// [ODM2 controlled vocabulary](http://vocabulary.odm2.org/units/); +/// "microsiemenPerCentimeter" (µS/cm) +#define ANALOGELECCONDUCTIVITY_EC_UNIT_NAME "microsiemenPerCentimeter" +/// @brief Default variable short code; "anlgEc" +#define ANALOGELECCONDUCTIVITY_EC_DEFAULT_CODE "anlgEc" +/**@}*/ /** - * @brief Class for the analog Electrical Conductivity monitor + * @brief Class for the analog [Electrical Conductivity monitor](@ref + * sensor_analog_cond) * * @ingroup sensor_analog_cond */ @@ -390,11 +395,10 @@ class AnalogElecConductivity : public Sensor { }; /** - * @brief The variable class used for electricalConductivity measured using an - * analog pin connected to electrodes submerged in the medium + * @brief The Variable sub-class used for electrical conductivity measured using + * an analog pin connected to electrodes submerged in the medium * * @ingroup sensor_analog_cond - * */ class AnalogElecConductivity_EC : public Variable { public: diff --git a/src/sensors/ApogeeSQ212.h b/src/sensors/ApogeeSQ212.h index 98205325c..48102acbe 100644 --- a/src/sensors/ApogeeSQ212.h +++ b/src/sensors/ApogeeSQ212.h @@ -141,6 +141,15 @@ * {{ @ref ApogeeSQ212_PAR }} */ /**@{*/ +#ifdef MS_USE_ADS1015 +/// @brief Decimals places in string representation; PAR should have 0 when +/// using an ADS1015. +#define SQ212_PAR_RESOLUTION 0 +#else +/// @brief Decimals places in string representation; PAR should have 4 when +/// using an ADS1115. +#define SQ212_PAR_RESOLUTION 4 +#endif /// Variable number; PAR is stored in sensorValues[0]. #define SQ212_PAR_VAR_NUM 0 /// @brief Variable name in [ODM2 controlled @@ -153,15 +162,6 @@ #define SQ212_PAR_UNIT_NAME "microeinsteinPerSquareMeterPerSecond" /// @brief Default variable short code; "photosyntheticallyActiveRadiation" #define SQ212_PAR_DEFAULT_CODE "photosyntheticallyActiveRadiation" -#ifdef MS_USE_ADS1015 -/// @brief Decimals places in string representation; PAR should have 0 when -/// using an ADS1015. -#define SQ212_PAR_RESOLUTION 0 -#else -/// @brief Decimals places in string representation; PAR should have 4 when -/// using an ADS1115. -#define SQ212_PAR_RESOLUTION 4 -#endif /**@}*/ /** From 56497ea046bd8a78fa90ed62ad2c6b620a06598e Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 12 Jun 2024 15:35:15 -0400 Subject: [PATCH 077/138] Re-add job for component inclusion Signed-off-by: Sara Damiano --- .github/workflows/build_documentation.yaml | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/.github/workflows/build_documentation.yaml b/.github/workflows/build_documentation.yaml index 5c3180fe4..43d1b3848 100644 --- a/.github/workflows/build_documentation.yaml +++ b/.github/workflows/build_documentation.yaml @@ -22,6 +22,53 @@ concurrency: cancel-in-progress: true jobs: + check_menu_inclusion: + runs-on: ubuntu-latest + if: ${{ ! contains(github.event.head_commit.message, 'ci skip') }} + name: Check that all classes are documented in the menu-a-la-carte example + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + # Using answer from here to get the exit code and pass the output: https://stackoverflow.com/questions/59191913/how-do-i-get-the-output-of-a-specific-step-in-github-actions + - name: check for classes in the menu example + id: check_component + continue-on-error: true + run: | + cd $GITHUB_WORKSPACE/continuous_integration + python check_component_inclusion.py 2>&1 | tee check_component.log + result_code=${PIPESTATUS[0]} + missing_menu_docs=$(cat check_component.log) + missing_menu_docs="${missing_menu_docs//'%'/'%25'}" + missing_menu_docs="${missing_menu_docs//$'\n'/'%0A'}" + missing_menu_docs="${missing_menu_docs//$'\r'/'%0D'}" + echo "missing_menu_docs=missing_menu_docs" >> $GITHUB_OUTPUT + if [[ $result_code ]]; then + echo "$(cat check_component.log)" >> $GITHUB_STEP_SUMMARY + else + echo "Valid library.json =)" >> $GITHUB_STEP_SUMMARY + fi + echo "Finished menu inclusion verification" + exit $result_code + + - name: Create commit comment + uses: peter-evans/commit-comment@v3 + if: steps.check_component.outcome=='failure' + with: + body: | + All sensor and variable subclasses must be included in the Menu a la Carte example + ${{ steps.check_component.outputs.missing_menu_docs }} + + - name: Fail if cannot find all menu flags + id: verification_failure + if: steps.check_component.outcome=='failure' + run: exit 1 + doc_build: if: ${{ ! contains(github.event.head_commit.message, 'ci skip') }} name: Build documentation From adb4073205e0a62583636b514ecb83579cdd94d1 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 12 Jun 2024 15:36:41 -0400 Subject: [PATCH 078/138] Don't generate dot graphs m.css won't use Signed-off-by: Sara Damiano --- docs/Doxyfile | 20 ++++++++++---------- docs/mcss-conf.py | 4 ++++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/Doxyfile b/docs/Doxyfile index 2d8ef48b5..2e9a286dc 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -2661,7 +2661,7 @@ DOT_FONTPATH = # Possible values are: NO, YES, TEXT, GRAPH and BUILTIN. # The default value is: YES. -CLASS_GRAPH = YES +CLASS_GRAPH = NO # If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a # graph for each documented class showing the direct and indirect implementation @@ -2673,7 +2673,7 @@ CLASS_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -COLLABORATION_GRAPH = YES +COLLABORATION_GRAPH = NO # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for # groups, showing the direct groups dependencies. Explicit enabling a group @@ -2684,7 +2684,7 @@ COLLABORATION_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -GROUP_GRAPHS = YES +GROUP_GRAPHS = NO # If the UML_LOOK tag is set to YES, doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling @@ -2735,7 +2735,7 @@ DOT_WRAP_THRESHOLD = 17 # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -TEMPLATE_RELATIONS = YES +TEMPLATE_RELATIONS = NO # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to # YES then doxygen will generate a graph for each documented file showing the @@ -2746,7 +2746,7 @@ TEMPLATE_RELATIONS = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDE_GRAPH = YES +INCLUDE_GRAPH = NO # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then doxygen will generate a graph for each documented file showing @@ -2758,7 +2758,7 @@ INCLUDE_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDED_BY_GRAPH = YES +INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH tag is set to YES then doxygen will generate a call # dependency graph for every global function or class method. @@ -2770,7 +2770,7 @@ INCLUDED_BY_GRAPH = YES # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -CALL_GRAPH = YES +CALL_GRAPH = NO # If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller # dependency graph for every global function or class method. @@ -2782,14 +2782,14 @@ CALL_GRAPH = YES # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -CALLER_GRAPH = YES +CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical # hierarchy of all classes instead of a textual one. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -GRAPHICAL_HIERARCHY = YES +GRAPHICAL_HIERARCHY = NO # If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the # dependencies a directory has on other directories in a graphical way. The @@ -2801,7 +2801,7 @@ GRAPHICAL_HIERARCHY = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -DIRECTORY_GRAPH = YES +DIRECTORY_GRAPH = NO # The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels # of child directories generated in directory dependency graphs by dot. diff --git a/docs/mcss-conf.py b/docs/mcss-conf.py index 6ce174b44..990cb59a5 100644 --- a/docs/mcss-conf.py +++ b/docs/mcss-conf.py @@ -124,3 +124,7 @@ STYLESHEETS = [ "css/m-EnviroDIY+documentation.compiled.css", ] +EXTRA_FILES = ["gp-desktop-logo.png", "gp-mobile-logo.png", "gp-scrolling-logo.png"] +DESKTOP_LOGO = "gp-desktop-logo.png" +MOBILE_LOGO = "gp-mobile-logo.png" +SCROLLING_LOGO = "gp-scrolling-logo.png" From 5a3714dba24006423930566c0474441f474fc6b0 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 12 Jun 2024 17:03:17 -0400 Subject: [PATCH 079/138] Move NIST macros, clean IP's Signed-off-by: Sara Damiano --- src/modems/DigiXBeeWifi.cpp | 17 +++---- src/modems/DigiXBeeWifi.h | 18 +------ src/modems/LoggerModemMacros.h | 92 ++++++++++++++++++++-------------- 3 files changed, 61 insertions(+), 66 deletions(-) diff --git a/src/modems/DigiXBeeWifi.cpp b/src/modems/DigiXBeeWifi.cpp index 224bf6f47..21a6d812b 100644 --- a/src/modems/DigiXBeeWifi.cpp +++ b/src/modems/DigiXBeeWifi.cpp @@ -389,19 +389,16 @@ uint32_t DigiXBeeWifi::getNISTTime(void) { // These are is the IP address of time-[a,b,c,d]-wwv.nist.gov // XBee's address lookup falters on time.nist.gov - const char ipAddr[NIST_SERVER_RETRYS][IP_STR_LEN] = { - {"132, 163, 97, 1"}, - {"132, 163, 97, 2"}, - {"132, 163, 97, 3"}, - {"132, 163, 97, 4"}}; - IPAddress ip1(132, 163, 97, 1); // Initialize - ip1.fromString(ipAddr[i]); - MS_DBG(F("NIST lookup mdmIP["), i, "/", NIST_SERVER_RETRYS, - F("] with "), ip1); + IPAddress nistIPs[] = { + IPAddress(132, 163, 97, 1), IPAddress(132, 163, 97, 2), + IPAddress(132, 163, 97, 3), IPAddress(132, 163, 97, 4), + IPAddress(132, 163, 97, 6), IPAddress(132, 163, 97, 8)}; + MS_DBG(F("\nConnecting to NIST daytime Server at ip"), nistIPs[i], + F("attempt"), i, F("of"), NIST_SERVER_RETRYS); // NOTE: This "connect" only sets up the connection parameters, the TCP // socket isn't actually opened until we first send data (the '!' below) - connectionMade = gsmClient.connect(ip1, TIME_PROTOCOL_PORT); + connectionMade = gsmClient.connect(nistIPs[i], TIME_PROTOCOL_PORT); // Need to send something before connection is made gsmClient.println('!'); diff --git a/src/modems/DigiXBeeWifi.h b/src/modems/DigiXBeeWifi.h index 67636a489..11c7c7110 100644 --- a/src/modems/DigiXBeeWifi.h +++ b/src/modems/DigiXBeeWifi.h @@ -81,27 +81,11 @@ #endif /** - * @brief This causes the Xbee to reset after this number of transmission + * @brief This causes the WiFi XBee to reset after this number of transmission * attempts */ #define XBEE_RESET_THRESHOLD 4 -// Try up to 4 NIST IP addresses attempting to get a timestamp from NIST -#if !defined NIST_SERVER_RETRYS -/** - * @brief The number of retry attempts when connecting to the NIST server. - */ -#define NIST_SERVER_RETRYS 4 -#endif // NIST_SERVER_RETRYS -/** - * @brief The port hosting the NIST "time" protocol (37) - */ -#define TIME_PROTOCOL_PORT 37 -/** - * @brief The length of the NIST IP address (18) - */ -#define IP_STR_LEN 18 - /** * @brief The class for the [Digi XBee](@ref modem_digi) * [S6B wifi](@ref modem_digi_wifi) module operating in Digi's "transparent" diff --git a/src/modems/LoggerModemMacros.h b/src/modems/LoggerModemMacros.h index 167e8883d..1d260bb87 100644 --- a/src/modems/LoggerModemMacros.h +++ b/src/modems/LoggerModemMacros.h @@ -454,6 +454,18 @@ } #endif // #if defined TINY_GSM_MODEM_HAS_GPRS +/** + * @brief The port hosting the NIST "time" protocol (37) + */ +#define TIME_PROTOCOL_PORT 37 + +// Try up to 4 NIST IP addresses attempting to get a timestamp from NIST +#if !defined NIST_SERVER_RETRYS || defined(DOXYGEN) +/** + * @brief The number of retry attempts when connecting to the NIST server. + */ +#define NIST_SERVER_RETRYS 4 +#endif // NIST_SERVER_RETRYS /** * @brief Creates a getNISTTime() function for a specific modem subclass. @@ -474,45 +486,47 @@ * subclass. * */ -#define MS_MODEM_GET_NIST_TIME(specificModem) \ - uint32_t specificModem::getNISTTime(void) { \ - /** Check for and bail if not connected to the internet. */ \ - if (!isInternetAvailable()) { \ - MS_DBG(F("No internet connection, cannot connect to NIST.")); \ - return 0; \ - } \ - \ - /** Try up to 12 times to get a timestamp from NIST. */ \ - for (uint8_t i = 0; i < 12; i++) { \ - while (millis() < _lastNISTrequest + 4000) { /* wait */ \ - } \ - \ - /** Make TCP connection. */ \ - MS_DBG(F("\nConnecting to NIST daytime Server")); \ - bool connectionMade = gsmClient.connect("time.nist.gov", 37, 15); \ - \ - /** Wait up to 5 seconds for a response. */ \ - if (connectionMade) { \ - uint32_t start = millis(); \ - while (gsmClient && gsmClient.available() < 4 && \ - millis() - start < 5000L) {} \ - \ - if (gsmClient.available() >= 4) { \ - MS_DBG(F("NIST responded after"), millis() - start, \ - F("ms")); \ - byte response[4] = {0}; \ - gsmClient.read(response, 4); \ - if (gsmClient.connected()) gsmClient.stop(); \ - return parseNISTBytes(response); \ - } else { \ - MS_DBG(F("NIST Time server did not respond!")); \ - if (gsmClient.connected()) gsmClient.stop(); \ - } \ - } else { \ - MS_DBG(F("Unable to open TCP to NIST!")); \ - } \ - } \ - return 0; \ +#define MS_MODEM_GET_NIST_TIME(specificModem) \ + uint32_t specificModem::getNISTTime(void) { \ + /** Check for and bail if not connected to the internet. */ \ + if (!isInternetAvailable()) { \ + MS_DBG(F("No internet connection, cannot connect to NIST.")); \ + return 0; \ + } \ + \ + /** Try up to 12 times to get a timestamp from NIST. */ \ + for (uint8_t i = 0; i < 12; i++) { \ + while (millis() < _lastNISTrequest + 4000) { /* wait */ \ + } \ + \ + /** Make TCP connection. */ \ + MS_DBG(F("\nConnecting to NIST daytime Server")); \ + bool connectionMade = gsmClient.connect("time.nist.gov", \ + TIME_PROTOCOL_PORT, 15); \ + \ + /** Wait up to 5 seconds for a response. */ \ + if (connectionMade) { \ + uint32_t start = millis(); \ + while (gsmClient && \ + gsmClient.available() < NIST_SERVER_RETRYS && \ + millis() - start < 5000L) {} \ + \ + if (gsmClient.available() >= 4) { \ + MS_DBG(F("NIST responded after"), millis() - start, \ + F("ms")); \ + byte response[4] = {0}; \ + gsmClient.read(response, 4); \ + if (gsmClient.connected()) gsmClient.stop(); \ + return parseNISTBytes(response); \ + } else { \ + MS_DBG(F("NIST Time server did not respond!")); \ + if (gsmClient.connected()) gsmClient.stop(); \ + } \ + } else { \ + MS_DBG(F("Unable to open TCP to NIST!")); \ + } \ + } \ + return 0; \ } #if defined(TINY_GSM_MODEM_XBEE) || defined(TINY_GSM_MODEM_ESP8266) From d1d48558da9fae4b81daeaa62a4659edd9c97317 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 14 Jun 2024 12:58:18 -0400 Subject: [PATCH 080/138] Markdown lint, fixes code block issues Signed-off-by: Sara Damiano --- docs/FAQ/Arduino-Streams.md | 6 +- docs/FAQ/Developer-Setup.md | 2 +- docs/FAQ/Power-Parasites.md | 16 +- docs/FAQ/Processor-Compatibility.md | 60 +-- docs/Getting-Started/Getting-Started.md | 41 +- docs/Getting-Started/Physical-Dependencies.md | 6 +- docs/Getting-Started/Terminology.md | 19 +- docs/Modem-Notes.md | 12 +- examples/DRWI_2G/ReadMe.md | 62 +-- examples/DRWI_DigiLTE/ReadMe.md | 66 +-- examples/DRWI_Mayfly1/ReadMe.md | 15 +- examples/DRWI_Mayfly1_WiFi/ReadMe.md | 17 +- examples/DRWI_NoCellular/ReadMe.md | 72 ++-- examples/DRWI_SIM7080LTE/ReadMe.md | 16 +- examples/ReadMe.md | 16 +- examples/baro_rho_correction/ReadMe.md | 44 +- examples/data_saving/ReadMe.md | 45 +- examples/double_logger/ReadMe.md | 36 +- examples/logging_to_MMW/ReadMe.md | 46 +- examples/logging_to_ThingSpeak/ReadMe.md | 48 ++- examples/menu_a_la_carte/ReadMe.md | 405 ++++++++---------- examples/simple_logging/ReadMe.md | 32 +- .../simple_logging_LearnEnviroDIY/ReadMe.md | 33 +- examples/single_sensor/ReadMe.md | 27 +- 24 files changed, 574 insertions(+), 568 deletions(-) diff --git a/docs/FAQ/Arduino-Streams.md b/docs/FAQ/Arduino-Streams.md index f1de3c8dd..e58a54e34 100644 --- a/docs/FAQ/Arduino-Streams.md +++ b/docs/FAQ/Arduino-Streams.md @@ -5,6 +5,7 @@ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [Notes on Arduino Streams and Software Serial](#notes-on-arduino-streams-and-software-serial) - [Hardware Serial](#hardware-serial) - [AltSoftSerial](#altsoftserial) @@ -16,6 +17,7 @@ In this library, the Arduino communicates with the computer for debugging, the modem for sending data, and some sensors (like the [MaxBotix MaxSonar](https://github.com/EnviroDIY/ModularSensors/wiki/MaxBotix-MaxSonar)) via instances of Arduino TTL [streams](https://www.arduino.cc/en/Reference/Stream). The streams can either be an instance of + - [serial (hardware serial)](https://www.arduino.cc/en/Reference/Serial), - [AltSoftSerial](https://github.com/PaulStoffregen/AltSoftSerial), - [NeoSWSerial](https://github.com/SRGDamia1/NeoSWSerial), @@ -50,7 +52,6 @@ If you would like to give your hardware serial port an easy-to-remember alias, y HardwareSerial* streamName = &Serial; ``` - ## AltSoftSerial If the [proper pins](https://www.pjrc.com/teensy/td_libs_AltSoftSerial.html) are available, **[AltSoftSerial](https://github.com/PaulStoffregen/AltSoftSerial)** by Paul Stoffregen is also superior to SoftwareSerial, especially at slow baud rates. @@ -68,7 +69,6 @@ AltSoftSerial streamName. // Create an instance of AltSoftSerial ``` - ## NeoSWSerial Another possible serial port emulator is [NeoSWSerial](https://github.com/SRGDamia1/NeoSWSerial). @@ -109,7 +109,6 @@ Additionally, for the EnviroDIY modified version of SoftwareSerial, (or NeoSWSer enableInterrupt(rx_pin, neoSSerial1ISR, CHANGE); ``` - ## Neutered SoftwareSerial [The EnviroDIY modified version of SoftwareSerial](https://github.com/EnviroDIY/SoftwaterSerial_ExternalInts) removes direct interrupt control from the SoftwareSerial library, making it dependent on another interrupt library, but able to be compiled with ModularSensors. @@ -136,7 +135,6 @@ Additionally, for the EnviroDIY modified version of SoftwareSerial, you must ena enableInterrupt(rx_pin, SoftwareSerial_ExtInts::handle_interrupt, CHANGE); ``` - ## SAMD SERCOMs Example code for creating more serial ports on an Adafruit feather M0 using the SERCOMs is available [in the menu a la carte example](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_samd_serial_ports). diff --git a/docs/FAQ/Developer-Setup.md b/docs/FAQ/Developer-Setup.md index 2ece6a18e..67f1ec915 100644 --- a/docs/FAQ/Developer-Setup.md +++ b/docs/FAQ/Developer-Setup.md @@ -161,6 +161,6 @@ build_flags = build_unflags = -D USE_TINYUSB ``` -While you're working on development, there is *extensive* debugging text built into this library. +While you're working on development, there is _extensive_ debugging text built into this library. More on that is in the [Code Debugging](https://github.com/EnviroDIY/ModularSensors/wiki/Code-Debugging) page. In fact, there is _so much_ debugging that turning it on universally through a build flag will cause the program to be too big to fit on a Mayfly and will likely crash a SAMD board's on-board USB drivers. diff --git a/docs/FAQ/Power-Parasites.md b/docs/FAQ/Power-Parasites.md index d22931f99..79cd4cfe8 100644 --- a/docs/FAQ/Power-Parasites.md +++ b/docs/FAQ/Power-Parasites.md @@ -9,17 +9,17 @@ For most sensors, this library attempts to set all data pins low when sending th If you are still seeing "parasitic" power draw, here are some work-arounds you can try: - For sensors (and adapters) drawing power over a serial line: - - Write-out your entire loop function. + - Write-out your entire loop function. (Don't just use `logData()`.) - - Add a `SerialPortName.begin(BAUD);` statement to the beginning of your loop, before `sensorsPowerUp()`. - - After `sensorsPowerDown()` add `SerialPortName.end(BAUD);`. - - After "ending" the serial communication, explicitly set your Rx and Tx pins low using `digitalWrite(#, LOW);`. + - Add a `SerialPortName.begin(BAUD);` statement to the beginning of your loop, before `sensorsPowerUp()`. + - After `sensorsPowerDown()` add `SerialPortName.end(BAUD);`. + - After "ending" the serial communication, explicitly set your Rx and Tx pins low using `digitalWrite(#, LOW);`. - For sensors drawing power over I2C: - - Many (most?) boards have external pull-up resistors on the hardware I2C/Wire pins which cannot be disconnected from the main power supply. + - Many (most?) boards have external pull-up resistors on the hardware I2C/Wire pins which cannot be disconnected from the main power supply. This means I2C parasitic power draw is best solved via hardware, not software. - - Use a specially designed I2C isolator - - Use a generic opto-isolator or other type of isolator on both the SCL and SDA lines - - In this future, this library _may_ offer the option of using software I2C, which would allow you to use the same technique as is currently usable to stop serial parasitic draw. + - Use a specially designed I2C isolator + - Use a generic opto-isolator or other type of isolator on both the SCL and SDA lines + - In this future, this library _may_ offer the option of using software I2C, which would allow you to use the same technique as is currently usable to stop serial parasitic draw. Until such an update happens, however, hardware solutions are required. The ["data_saving"](@todo add link to loop of datasaving example) example shows setting ending a serial stream and seeting pins low to prevent an RS485 adapter from drawing power during sleep. diff --git a/docs/FAQ/Processor-Compatibility.md b/docs/FAQ/Processor-Compatibility.md index 9cd49bcce..ae8a36c87 100644 --- a/docs/FAQ/Processor-Compatibility.md +++ b/docs/FAQ/Processor-Compatibility.md @@ -5,14 +5,15 @@ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) -- [Processor Compatibility ](#processor-compatibility-) - - [AtMega1284p (EnviroDIY Mayfly, Sodaq Mbili, Mighty 1284) ](#atmega1284p-envirodiy-mayfly-sodaq-mbili-mighty-1284-) - - [AtSAMD21 (Arduino Zero, Adafruit Feather M0, Sodaq Autonomo) ](#atsamd21-arduino-zero-adafruit-feather-m0-sodaq-autonomo-) - - [AtMega2560 (Arduino Mega) ](#atmega2560-arduino-mega-) - - [AtMega644p (Sanguino) ](#atmega644p-sanguino-) - - [AtMega328p (Arduino Uno, Duemilanove, LilyPad, Mini, Seeeduino Stalker, etc) ](#atmega328p-arduino-uno-duemilanove-lilypad-mini-seeeduino-stalker-etc-) - - [AtMega32u4 (Arduino Leonardo/Micro, Adafruit Flora/Feather, etc) ](#atmega32u4-arduino-leonardomicro-adafruit-florafeather-etc-) - - [Unsupported Processors ](#unsupported-processors-) + +- [Processor Compatibility](#processor-compatibility) + - [AtMega1284p (EnviroDIY Mayfly, Sodaq Mbili, Mighty 1284)](#atmega1284p-envirodiy-mayfly-sodaq-mbili-mighty-1284) + - [AtSAMD21 (Arduino Zero, Adafruit Feather M0, Sodaq Autonomo)](#atsamd21-arduino-zero-adafruit-feather-m0-sodaq-autonomo) + - [AtMega2560 (Arduino Mega)](#atmega2560-arduino-mega) + - [AtMega644p (Sanguino)](#atmega644p-sanguino) + - [AtMega328p (Arduino Uno, Duemilanove, LilyPad, Mini, Seeeduino Stalker, etc)](#atmega328p-arduino-uno-duemilanove-lilypad-mini-seeeduino-stalker-etc) + - [AtMega32u4 (Arduino Leonardo/Micro, Adafruit Flora/Feather, etc)](#atmega32u4-arduino-leonardomicro-adafruit-florafeather-etc) + - [Unsupported Processors](#unsupported-processors) [//]: # ( End GitHub Only ) @@ -32,17 +33,19 @@ Chip select/slave select is pin 12 on a Mayfly and card detect can be set to pin CS/SS and CD pins may vary for other boards. - There is a single I2C (Wire) interface on pins 17 (SDA) and 16 (SCL). - This processor has two built-in hardware TTL serial ports, Serial and Serial1 - - On most boards, Serial is connected to the FDTI chip for USB communication with the computer. + - On most boards, Serial is connected to the FDTI chip for USB communication with the computer. On both the Mayfly and the Mbili Serial1 is wired to the "Bee" sockets for communication with the modem. - AltSoftSerial can be used on pins 5 (Tx) and 6 (Rx) on the Mayfly or Mbili. Pin 4 should not be used while using AltSoftSerial on the Mayfly or Mbili. - - Unfortunately, the Rx and Tx pins are on different Grove plugs on both the Mayfly and the Mbili making AltSoftSerial somewhat inconvenient to use. + - Unfortunately, the Rx and Tx pins are on different Grove plugs on both the Mayfly and the Mbili making AltSoftSerial somewhat inconvenient to use. - AltSoftSerial can be used on pins 13 (Tx) and 14 (Rx) on the Mighty 1284 and other 1284p boards. Pin 12 should not be used while using AltSoftSerial on the Mighty 1284. - Any digital pin can be used with NeoSWSerial, SoftwareSerial_ExtInts, or SDI-12. + ___ ## AtSAMD21 (Arduino Zero, Adafruit Feather M0, Sodaq Autonomo) + Fully supported [Datasheet Summary](https://github.com/EnviroDIY/ModularSensors/wiki/Processor-Datasheets/Atmel-SAMD21-Datasheet-Summary.pdf) @@ -57,15 +60,15 @@ At this time, the AtSAMD21 is only supported using the internal clock, but suppo Most boards connect the USB pins to a mini or microUSB connector for the computer connection. Depending on the software core of the board, you send data to the USB port as either "USBSerial" or simply "Serial". - Most variants have 2 hardware TTL serial ports ("Serial" on pins 30 (TX) and 31 (RX) and "Serial1" on pins 0 (TX) and 1 (RX)) configured by default. - - On an Arduino Zero "Serial" goes to the EDBG programming port. - - On a Sodaq Autonomo "Serial1" goes to the "Bee" port. - - On an Adafruit Feather M0 only "Serial1" is configured, "Serial" will go to the native USB port. + - On an Arduino Zero "Serial" goes to the EDBG programming port. + - On a Sodaq Autonomo "Serial1" goes to the "Bee" port. + - On an Adafruit Feather M0 only "Serial1" is configured, "Serial" will go to the native USB port. - Most variants have one SPI port configured by default (likely pins 22 (MISO), 23 (MOSI), and 24 (SCK)). Chip select/slave select and card detect pins vary by board. - Most variants have one I2C (Wire) interface configured by default (likely pins 20 (SDA) and 21 (SCL)). - There are up to _6_ total "sercom" ports hard which can be configured for either hardware serial, SPI, or I2C (wire) communication on this processor. -See https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports/overview for more instructions on how to configure these ports, if you need them. -There are also examples for an Adafruit feather found in the menu a la carte example: https://github.com/EnviroDIY/ModularSensors/tree/master/examples/menu_a_la_carte +See for more instructions on how to configure these ports, if you need them. +There are also examples for an Adafruit feather found in the menu a la carte example: - AltSoftSerial is not supported on the AtSAMD21. - SoftwareSerial_ExtInts is not supported on the AtSAMD21. - NeoSWSerial is not supported at all on the AtSAMD21. @@ -75,9 +78,11 @@ If you need to debug, I recommend using a serial port monitor like [Tera Term](h Otherwise, you will have to rely on lights on your alert pin or your modem to verify the processor is waking/sleeping properly. - There are also some oddities with debugging on the SAMD21 where turning on some of the debugging code will cause the native USB to fail (and the board appear to be bricked). Turn off the debugging and double-tap to reset and reprogram if this happens. + ___ ## AtMega2560 (Arduino Mega) + Should be fully functional, but untested. - An external DS3231 or DS3232 RTC is required. @@ -88,6 +93,7 @@ Chip select/slave select is on pin 53. - If you still need more serial ports, AltSoftSerial can be used on pins 46 (Tx) and 48 (Rx). Pins 44 and 45 cannot be used while using AltSoftSerial on the AtMega2560. - Pins 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), and A15 (69) can be used with NeoSWSerial, SoftwareSerial_ExtInts, or SDI-12. + ___ ## AtMega644p (Sanguino) @@ -103,6 +109,7 @@ Chip select/slave select and card detect pins vary by board. - AltSoftSerial can be used on pins 13 (Tx) and 14 (Rx). Pin 12 cannot be used while using AltSoftSerial on the AtMega644p. - Any digital pin can be used with NeoSWSerial, SoftwareSerial_ExtInts, or SDI-12. + ___ ## AtMega328p (Arduino Uno, Duemilanove, LilyPad, Mini, Seeeduino Stalker, etc) @@ -119,9 +126,11 @@ SS/CS and CD pins may vary for other boards. - AltSoftSerial can be used on pins 9 (Tx) and 8 (Rx). Pin 10 cannot be used while using AltSoftSerial on the AtMega328p. - Any digital pin can be used with NeoSWSerial, SoftwareSerial_ExtInts, or SDI-12. + ___ ## AtMega32u4 (Arduino Leonardo/Micro, Adafruit Flora/Feather, etc) + All functions are supported, but processor doesn't have sufficient power to use all of the functionality of the library. You will only be able to use a small number of sensors at one time and may not be able to log data. @@ -141,26 +150,27 @@ Chip select/slave select and card detect pins vary by board. - Because the USB controller is built into the processor, your USB serial connection will close as soon as the processor goes to sleep. If you need to debug, I recommend using a serial port monitor like Tera Term which will automatically renew its connection with the serial port when it connects and disconnects. Otherwise, you will have to rely on lights on your alert pin or your modem to verify the processor is waking/sleeping properly. + ___ ## Unsupported Processors - **ESP8266/ESP32** - Supported _only_ as a communications module (modem) with the default AT command firmware, not supported as an independent controller - **AtSAM3X (Arduino Due)** - Unsupported at this time due to clock and sleep issues. - - There is one SPI port on pins 74 (MISO), 76 (MOSI), and 75 (SCK). + - There is one SPI port on pins 74 (MISO), 76 (MOSI), and 75 (SCK). Pins 4, 10 and pin 52 can be used for CS/SS. - - There are I2C (Wire) interfaces on pins 20 (SDA) and 21 (SCL) and 70 (SDA1) and 71 (SCL1). - - This processor has one hardware serial port, USBSerial, which can _only_ be used for USB communication with a computer - - There are three additional 3.3V TTL serial ports: Serial1 on pins 19 (RX) and 18 (TX); Serial2 on pins 17 (RX) and 16 (TX), Serial3 on pins 15 (RX) and 14 (TX). + - There are I2C (Wire) interfaces on pins 20 (SDA) and 21 (SCL) and 70 (SDA1) and 71 (SCL1). + - This processor has one hardware serial port, USBSerial, which can _only_ be used for USB communication with a computer + - There are three additional 3.3V TTL serial ports: Serial1 on pins 19 (RX) and 18 (TX); Serial2 on pins 17 (RX) and 16 (TX), Serial3 on pins 15 (RX) and 14 (TX). Pins 0 and 1 are also connected to the corresponding pins of the ATmega16U2 USB-to-TTL Serial chip, which is connected to the USB debug port. - - AltSoftSerial is not directly supported on the AtSAM3X. - - SoftwareSerial_ExtInts is not supported on the AtSAM3X. - - SDI-12 is not supported on the AtSAM3X - - Any digital pin can be used with SDI-12. - - [Datasheet](https://github.com/EnviroDIY/ModularSensors/wiki/Processor-Datasheets/Atmel-AM3X-SAM3A-Datasheet.pdf) + - AltSoftSerial is not directly supported on the AtSAM3X. + - SoftwareSerial_ExtInts is not supported on the AtSAM3X. + - SDI-12 is not supported on the AtSAM3X + - Any digital pin can be used with SDI-12. + - [Datasheet](https://github.com/EnviroDIY/ModularSensors/wiki/Processor-Datasheets/Atmel-AM3X-SAM3A-Datasheet.pdf) - **ATtiny** - Unsupported. This chip has too little processing power and far too few pins and communication ports to ever use this library. - - [Datasheet](https://github.com/EnviroDIY/ModularSensors/wiki/Processor-Datasheets/Atmel-ATtiny25-45-85-Datasheet.pdf) + - [Datasheet](https://github.com/EnviroDIY/ModularSensors/wiki/Processor-Datasheets/Atmel-ATtiny25-45-85-Datasheet.pdf) - **Teensy 2.x/3.x** - Unsupported - **STM32** - Unsupported - **Nordic nRF52840** - Unsupported diff --git a/docs/Getting-Started/Getting-Started.md b/docs/Getting-Started/Getting-Started.md index b252b9306..14c54baae 100644 --- a/docs/Getting-Started/Getting-Started.md +++ b/docs/Getting-Started/Getting-Started.md @@ -5,6 +5,7 @@ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [Getting Started](#getting-started) - [IDE and Driver Installation](#ide-and-driver-installation) - [Library Installation](#library-installation) @@ -23,15 +24,15 @@ There is an [extensive manual](https://www.envirodiy.org/mayfly-sensor-station-m To interface with your board and send it programs, you'll need to install drivers and an [IDE](https://en.wikipedia.org/wiki/Integrated_development_environment) or editor with a compiler on your computer. Many Arduino style boards, including the EnviroDIY Mayfly, interface with the computer using an FTDI chip as a virtual com port. -The drivers and installation instructions for them are available on the FTDI website: https://www.ftdichip.com/Drivers/VCP.htm. +The drivers and installation instructions for them are available on the FTDI website: . **You must be an administrator on your computer to install drivers!** If you've used an Arduino before or installed the Arduino IDE, it's likely that these drivers are already on your computer. -Adafruit has a nice grouping of drivers for other boards and installation instructions here: https://learn.adafruit.com/adafruit-arduino-ide-setup/windows-driver-installation. +Adafruit has a nice grouping of drivers for other boards and installation instructions here: . After the drivers, you should install the IDE. Even if you've used the official Arduino IDE before, I _very, **very** strongly_ suggest installing and using [PlatformIO](https://platformio.org/) on either [Visual Studio Code](https://code.visualstudio.com/) or [Atom](https://atom.io/) -Visual Studio code can be downloaded from https://code.visualstudio.com/ and installed following the directions on that website. +Visual Studio code can be downloaded from and installed following the directions on that website. You do not need to be an administrator to install it. Once VSCode has been installed, open it. On the picture menu on the left click the extensions button. @@ -51,7 +52,6 @@ Because this library has a large number of dependencies, I, again, _very, **very If you use PlatformIO, the library will automatically be installed when you list it in your dependencies in your project's platformio.ini file. If you really must use the Arduino IDE, this library and all is dependencies can be downloaded in one large zip file [here](https://github.com/EnviroDIY/Libraries/blob/master/libraries.zip?raw=true). - ## Setting the Clock Most of this library's functionality depends on having a working DS3231 real time clock attached to your Arduino, so the first thing you need to do is get the time right. @@ -59,7 +59,7 @@ For the rank beginners out there; I feel your pain. When I first started with an Arduino, the step of setting the clock took me _**three days**_ to figure out. (Yes, three days. Yes, I was that lost! -My background is *not* in programming or engineering.) +My background is _not_ in programming or engineering.) After that experience, nearly the first program I decided was needed was an easier way to synchronize the clock. In fact, almost all of the example programs in this library that use a modern to connect to the internet will attempt to check the clock at start up. But, for safety, I suggest you set the clock separately. @@ -77,14 +77,13 @@ Pick whatever board you'll be working with from the drop down. For a new project, it's easiest to let PlatformIO set everything up in a new folder. - Once PlatformIO sets up the new project, find and open the newly created platformio.ini file. It should be a short file with one `[platformio]` section and one `[env]` section for the board you selected earlier. - - In the `[platformio]` section add this line: `src_dir = .pio/libdeps/mayfly/EnviroDIY_DS3231/examples/PCsync` - - In the `[env]` section add this line: `lib_deps = EnviroDIY_DS3231` + - In the `[platformio]` section add this line: `src_dir = .pio/libdeps/mayfly/EnviroDIY_DS3231/examples/PCsync` + - In the `[env]` section add this line: `lib_deps = EnviroDIY_DS3231` - Upload to your board. You shouldn't have to open or modify the program at all. -- Download and run this tiny clock-sync program: https://github.com/EnviroDIY/Sodaq_DS3231/blob/master/examples/PCsync/PCsync.exe?raw=true +- Download and run this tiny clock-sync program: - Your clock should be set! - ## Writing Your Logger Program The set-up in for your logger program PlatformIO is pretty simple: @@ -94,7 +93,7 @@ Pick whatever board you'll be working with. Again, it's easiest to let PlatformIO set everything up in a new folder. - Find and open the newly created platformio.ini file in your directory. In the `[env]` section add these lines: - - It is important that your configuration has the lib_ldf_mode and build flags set as show below. + - It is important that your configuration has the lib_ldf_mode and build flags set as show below. Without this, the library won't compile. ```ini @@ -110,13 +109,12 @@ build_flags = - Download the "ino" file for whatever example you think will be most similar to what you'll be doing. Put the ino into the src directory of your project. - - Delete main.cpp in that folder. + - Delete main.cpp in that folder. - Do a test build before changing the example just to make sure it compiles. Note: before compiling the first time, PlatformIO has to download the library and is dependencies so be patient. The download only happens once. - If the build succeeds, you're ready to move on. - ## Modifying the Examples There are a number of examples in the [examples](https://github.com/EnviroDIY/ModularSensors/tree/master/examples) folder for different logger functionalities. @@ -127,40 +125,39 @@ There's no reason you need to use the same pin assignments. Do make sure you create or reference all of the variables for your sensors in your variable array. The examples currently available are: + - [menu_a_la_carte](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/menu_a_la_carte) - - This shows most of the functions of the library at once. + - This shows most of the functions of the library at once. It has code in it for every possible sensor and modem and for both AVR and SAMD boards. It is also over 1500 lines long. - [single_sensor](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/single_sensor) - - This shows making use of the unified set of commands to print data from a MaxBotix ultrasonic range finder to the serial port. + - This shows making use of the unified set of commands to print data from a MaxBotix ultrasonic range finder to the serial port. It also shows creating a calculated variable which is the water depth. - [DRWI_CitSci](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/) - - This example uses the sensors and equipment standard groups participating in the DRWI Citizen Science project with the Stroud Water Research Center. + - This example uses the sensors and equipment standard groups participating in the DRWI Citizen Science project with the Stroud Water Research Center. It includes a Meter Hydros 21 (formerly know as a Decagon CTD), a Campbell OBS3+, and a Sodaq GPRSBee for communication. The results are saved to the SD card and posted to the Monitor My Watershed data portal. - [DRWI_NoCellular](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/DRWI_NoCellular) - - This also uses the sensors and equipment standard to the DRWI Citizen Science grant but omits the modem for circumstances where there is no cellular signal. + - This also uses the sensors and equipment standard to the DRWI Citizen Science grant but omits the modem for circumstances where there is no cellular signal. - [logging_to_ThingSpeak](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/logging_to_ThingSpeak) - - This uses an ESP8266 to send data to ThingSpeak. + - This uses an ESP8266 to send data to ThingSpeak. It also includes a Meter Hydros 21 (formerly know as a Decagon CTD) and a Campbell OBS3+. - [baro_rho_correction](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/baro_rho_correction) - - This example demonstrates how to work with calculated variables and calculates water depth by correcting the total pressure measured by a Measurement Specialties MS5803 with the atmospheric pressure measured by a Bosch BME280 environmental sensor and the temperature measured by a Maxim DS18 temperature probe. + - This example demonstrates how to work with calculated variables and calculates water depth by correcting the total pressure measured by a Measurement Specialties MS5803 with the atmospheric pressure measured by a Bosch BME280 environmental sensor and the temperature measured by a Maxim DS18 temperature probe. - [double_logger](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/double_logger) - - This is a more complicated example using two different logger instances to log data at two different intervals, in this case, an AM3215 logging every minute, while checking the battery voltage only every 5 minutes. + - This is a more complicated example using two different logger instances to log data at two different intervals, in this case, an AM3215 logging every minute, while checking the battery voltage only every 5 minutes. This showcases both how to use two different logging instances and how to use some of the functions to set up your own logging loop rather than using the logData() function. - [data_saving](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/) - - This is another double logger example, but in this case, both loggers are going at the same interval and the only difference between the loggers is the list of variables. + - This is another double logger example, but in this case, both loggers are going at the same interval and the only difference between the loggers is the list of variables. There are two sets of variables, all coming from Yosemitech sensors. Because each sensor outputs temperature and we don't want to waste cellular data sending out multiple nearly identical temperature values, we have one logger that logs every possible variable result to the SD card and another logger that sends only unique results to the EnviroDIY data portal. This example also shows how to stop power draw from an RS485 adapter with automatic flow detection. - ## Deploying your Station To start getting data from the wild, you'll need some [stuff](https://github.com/EnviroDIY/ModularSensors/wiki/Physical-Dependencies) to power your logger and keep it safe from the elements. There are [video instructions](https://www.envirodiy.org/videos/) on the EnviroDIY website showing how to prepare and install a typical steam-side logger box and seniors. - [//]: # ( @section page_getting_started_other Other Helpful Pages to Get Started ) [//]: # ( @subpage page_library_dependencies ) diff --git a/docs/Getting-Started/Physical-Dependencies.md b/docs/Getting-Started/Physical-Dependencies.md index d09693465..68be03dd6 100644 --- a/docs/Getting-Started/Physical-Dependencies.md +++ b/docs/Getting-Started/Physical-Dependencies.md @@ -5,13 +5,13 @@ The most banal functions of the library require only an AVR or SAMD processor, b - A sufficiently powerful AVR or SAMD processor mounted on some sort of circuit board. (See [Processor/Board Compatibility](https://envirodiy.github.io/ModularSensors/page_processor_compatibility.html) for more details on specific processors and boards that are supported.) - - For all AVR processors, you must also have a [Maxim DS3231](https://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html) high precision I2C real-time clock with the SQE/INT pin connected to a pin on your processor which supports either external or pin-change interrupts. - - For SAMD boards, this library makes use of their on-board (though less accurate) real-time clock. + - For all AVR processors, you must also have a [Maxim DS3231](https://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html) high precision I2C real-time clock with the SQE/INT pin connected to a pin on your processor which supports either external or pin-change interrupts. + - For SAMD boards, this library makes use of their on-board (though less accurate) real-time clock. - A SD card reader attached to the processor via SPI. - Environmental sensors - A battery to power the system - A solar charging circuit - A modem-type unit to communicate remote data (Optional for logging data, but required for sending data directly to the internet. - - The list of supported modems is available here: https://envirodiy.github.io/ModularSensors/index.html#mainpage_modems + - The list of supported modems is available here: - Protected water-proof enclosures and mountings for all of the above - An OTG cable to connect serial output from the board to a cell phone (Optional, but very helpful for debugging.) diff --git a/docs/Getting-Started/Terminology.md b/docs/Getting-Started/Terminology.md index 1ffbff081..41c001321 100644 --- a/docs/Getting-Started/Terminology.md +++ b/docs/Getting-Started/Terminology.md @@ -9,6 +9,7 @@ Within this library, a Sensor, a Variable, and a Logger mean very specific thing [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [Library Terminology](#library-terminology) - [Terms](#terms) - [Sensor](#sensor) @@ -29,14 +30,14 @@ They may be awoken or activated and then returned to a sleeping/low power use st The may need to be asked to begin a single reading or they may continuously return data. They _**must**_ be capable of returning the value of their readings to a logger of some type. -The detailed Sensor class documentation is here: https://envirodiy.github.io/ModularSensors/class_sensor.html +The detailed Sensor class documentation is here: ### Variable A Variable is a result value taken by a Sensor _or_ calculated from the results of one or more sensors. It is characterized by a name (what it is a measurement of), a unit of measurement, and a resolution. The [names](http://vocabulary.odm2.org/variablename/) and [units](http://vocabulary.odm2.org/units/) of measurements for all variables come from the controlled vocabularies developed for the ODM2 data system. -(http://vocabulary.odm2.org/) The resolution is determined by the method used to take the measurement by the sensor. +() The resolution is determined by the method used to take the measurement by the sensor. A variable may also be assigned a universally unique identifier (UUID) and a unique variable code. Many sensors are capable of measuring multiple variables at a single time. For example, a Meter Hydros 21 is a _sensor_. @@ -45,21 +46,21 @@ The variable named "specificConductance" has _units_ of microsiemens per centime Each measured variable is explicitly tied to the "parent" sensor that "notifies" the variable when a new value has been measured. Each calculated variable has a parent function returning a float which is the value for that variable. -The Variable class documentation is here: https://envirodiy.github.io/ModularSensors/class_variable.html +The Variable class documentation is here: Variables are grouped together into VariableArrays. -The VariableArray class documentation is here: https://envirodiy.github.io/ModularSensors/class_variable_array.html +The VariableArray class documentation is here: ### Logger A logger is a circuit board with a processor or microcontroller unit (MCU) that can control all functions of the modem and sensors that are attached to it and save the values of all variables measured by those sensors to an attached SD card. In this library, all loggers are Arduino-style small processor circuit boards. -The Logger class documentation is here: https://envirodiy.github.io/ModularSensors/class_logger.html +The Logger class documentation is here: ### Modem -![](https://en.wikipedia.org/wiki/Modem#/media/File:Analogue_modem_-_acoustic_coupler.jpg) +[![Old School Modem](https://upload.wikimedia.org/wikipedia/commons/e/e5/Analogue_modem_-_acoustic_coupler.jpg)](https://en.wikipedia.org/wiki/Modem) A modem is a [system on a chip](https://en.wikipedia.org/wiki/System_on_a_chip) or [system on a module](https://en.wikipedia.org/wiki/System_on_module) a that can communicate with the logger's MCU and with the world wide web. This doesn't mean something that makes [beeps and bloops](https://en.wikipedia.org/wiki/Modem#/media/File:Analogue_modem_-_acoustic_coupler.jpg) on the phone line. @@ -69,8 +70,7 @@ The two communcicate via serial lines. Within this library, the modem is represented as a loggerModem object. All loggerModem functions are heavily dependent on the [TinyGSM](https://github.com/EnviroDIY/TinyGSM) library. -The loggerModem class documentation is available here: https://envirodiy.github.io/ModularSensors/classlogger_modem.html - +The loggerModem class documentation is available here: ### DataPublisher @@ -78,8 +78,7 @@ Unlike the other components, a dataPublisher object doesn't represent any physic It's an object only in the sense of object oriented programming - not something you could hold. Within the functioning of the library, the dataPublisher "watches" the logger for new data and correctly formats and sends that data to some online web service. -The dataPublisher class documentation is available here: https://envirodiy.github.io/ModularSensors/classdata_publisher.html - +The dataPublisher class documentation is available here: ## Library Structure diff --git a/docs/Modem-Notes.md b/docs/Modem-Notes.md index 633d5cc72..f128d023b 100644 --- a/docs/Modem-Notes.md +++ b/docs/Modem-Notes.md @@ -5,6 +5,7 @@ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [Notes about Modems](#notes-about-modems) - [Summary of Classes to use for Various Manufactured Modules](#summary-of-classes-to-use-for-various-manufactured-modules) - [Default baud rates of supported modules](#default-baud-rates-of-supported-modules) @@ -17,7 +18,6 @@ If you are having trouble, please see the pages for the specific modems and the TinyGSM [getting started](https://github.com/vshymanskyy/TinyGSM#getting-started) and [troubleshooting](https://github.com/vshymanskyy/TinyGSM#troubleshooting) sections. - ## Summary of Classes to use for Various Manufactured Modules | Module | Class | @@ -78,7 +78,7 @@ Any model that requires a higher level of current (almost all of them) should be **The most common symptom of insufficient power is that the module will not connect to the internet.** Most modules are capable of serial communication and some level of functionality at current levels much below ideal, but will silently refuse to make a network connection. -@see https://github.com/vshymanskyy/TinyGSM/wiki/Powering-GSM-module +@see | Module | Operating Voltage | Minimum Current Required | Power Pin Label | | :----------------------------------: | :---------------: | :-------------------------------: | :-------------: | @@ -147,7 +147,6 @@ Here are the pin numbers to use for modules that can be attached directly to an | Sodaq UBee 3G (u-blox SARA U201) | 23 | 19 | -1 | 20 | | EnviroDIY LTE Bee (SIM7080G) | -1 | 19 | N/A | 239 | - ¹ To use the cellular Digi XBee's without the LTE adapter, your Mayfly must be at least v0.5b, you must use SJ13 to connect the Bee directly to the LiPo, and you must always have a battery connected to provide enough power for the XBee to make a cellular connection. If you turn off the Mayfly via its switch but leave the XBee connected as above, it will drain your battery very quickly. Disconnect the battery if you turn off the Mayfly. @@ -160,10 +159,10 @@ Instead, you must use the XBee's `CTS` pin (pin 12) which is connected to Mayfly 4 The LTE adapter switches pins 12 and 13 so that the true `STATUS` pin of the XBee is connected to Mayfly pin 19. You should set the argument `useCTSforStatus` to `false` in the bee constructor -5 I *strongly* recommend running a new wire along the back of the Mayfly to connect pin 5 of the XBee socket to pin A4. +5 I _strongly_ recommend running a new wire along the back of the Mayfly to connect pin 5 of the XBee socket to pin A4. This will enable you to use A4 as the reset pin which allows you to use deep sleep. -7 I *strongly* recommend running two new wires along the back of the Mayfly to connect pin 5 of the XBee socket to pin A4 and pin 18 of the XBee socket to A3. +7 I _strongly_ recommend running two new wires along the back of the Mayfly to connect pin 5 of the XBee socket to pin A4 and pin 18 of the XBee socket to A3. This will enable you to use A4 as the reset pin and A3 as the sleep request pin. With those connections made, the Dragino BG96 becomes the _**only**_ LTE module that can be run using only the 500mA regulator on the Mayfly (ie, without a separate battery connection for the modem). @@ -171,6 +170,7 @@ With those connections made, the Dragino BG96 becomes the _**only**_ LTE module 9 The EnviroDIY LTE Bee inverts the signal to the sleep request pin (`PWRKEY`) - which is also used for reset. To use it, you must add these commands to your setup: + ```cpp modem.setModemWakeLevel(HIGH); modem.setModemResetLevel(HIGH); @@ -194,7 +194,6 @@ Here are the pin numbers to use for modules that can be attached directly to an | Sodaq UBee LTE-M (u-blox SARA R410M) | 23 | 19 | A53 | 20 | | Sodaq UBee 3G (u-blox SARA U201) | 23 | 19 | A53 | 20 | - ¹ This assumes you have not changed solder jumper 18. If you have switched SJ18 to connect bee pin one directly to 3.3V, use -1. ² The Digi XBee reports ON/SLEEP_N on pin 13, but this is not connected to a Mayfly pin by default. @@ -205,6 +204,7 @@ Alternately (and preferably) you can change solder jumper 19 (SJ19) to connect b 4 The EnviroDIY LTE Bee inverts the signal to the sleep request pin (`PWRKEY`) - which is also used for reset. To use it, you must add these commands to your setup: + ```cpp modem.setModemWakeLevel(HIGH); modem.setModemResetLevel(HIGH); diff --git a/examples/DRWI_2G/ReadMe.md b/examples/DRWI_2G/ReadMe.md index 668db9cb6..19dbcc60d 100644 --- a/examples/DRWI_2G/ReadMe.md +++ b/examples/DRWI_2G/ReadMe.md @@ -3,11 +3,11 @@ This code was used for DRWI monitoring stations in 2016-2022. The 2G GPRSbee cellular boards no longer function in the USA, so this code should not be used and is only provided to archival and reference purposes. The exact hardware configuration used in this example: - * Mayfly v0.5b board - * SODAQ GPRSbee 2G cell module (with Hologram SIM card) - * Hydros21 CTD sensor - * Campbell OBS3+ turbidity sensor +- Mayfly v0.5b board +- SODAQ GPRSbee 2G cell module (with Hologram SIM card) +- Hydros21 CTD sensor +- Campbell OBS3+ turbidity sensor _______ @@ -16,37 +16,41 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [DRWI 2G Sites](#drwi-2g-sites) -- [Unique Features of the DRWI 2G Example](#unique-features-of-the-drwi-2g-example) -- [To Use this Example](#to-use-this-example) - - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) - - [Set the logger ID](#set-the-logger-id) - - [Set the calibration coefficients for the Campbell OBS3+](#set-the-calibration-coefficients-for-the-campbell-obs3) - - [Set the universally universal identifiers (UUID) for each variable](#set-the-universally-universal-identifiers-uuid-for-each-variable) - - [Upload!](#upload) + - [Unique Features of the DRWI 2G Example](#unique-features-of-the-drwi-2g-example) + - [To Use this Example](#to-use-this-example) + - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) + - [Set the logger ID](#set-the-logger-id) + - [Set the calibration coefficients for the Campbell OBS3+](#set-the-calibration-coefficients-for-the-campbell-obs3) + - [Set the universally universal identifiers (UUID) for each variable](#set-the-universally-universal-identifiers-uuid-for-each-variable) + - [Upload!](#upload) [//]: # ( End GitHub Only ) _______ -# Unique Features of the DRWI 2G Example +## Unique Features of the DRWI 2G Example + - Specifically for sites within the Delaware River Watershed Initiative. - Uses a Sodaq 2GBee for live data. -# To Use this Example +## To Use this Example -## Prepare and set up PlatformIO -- Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) +### Prepare and set up PlatformIO + +- Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal () - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/DRWI_CitSci/platformio.ini) file in the examples/DRWI_CitSci folder on GitHub. - - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. - - Without this, the program won't compile. + - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. + - Without this, the program won't compile. - Open [DRWI_CitSci.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/DRWI_CitSci/DRWI_CitSci.ino) and save it to your computer. - - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". - - Move it into the src directory of your project. - - Delete main.cpp in that folder. + - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". + - Move it into the src directory of your project. + - Delete main.cpp in that folder. + +### Set the logger ID -## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -54,12 +58,13 @@ _______ const char *LoggerID = "XXXX"; ``` -## Set the calibration coefficients for the Campbell OBS3+ +### Set the calibration coefficients for the Campbell OBS3+ + - The OBS3+ ships with a calibration certificate; you need this sheet! - Change _**all**_ of the the `0.000E+00` and `1.000E+00` values in this section of code to the values on that calibration sheet. Use numbers from the side of the calibration sheet that shows the calibration in _**volts**_. - - The sketch will not compile if these values are not entered properly. - - Do not change any values except those that are `0.000E+00` and `1.000E+00`! + - The sketch will not compile if these values are not entered properly. + - Do not change any values except those that are `0.000E+00` and `1.000E+00`! ```cpp // ========================================================================== @@ -83,8 +88,9 @@ const float OBSHigh_C = 0.000E+00; // "C" value [*high* range] CampbellOBS3 osb3high(OBS3Power, OBSHighADSChannel, OBSHigh_A, OBSHigh_B, OBSHigh_C, ADSi2c_addr, OBS3numberReadings); ``` -## Set the universally universal identifiers (UUID) for each variable -- Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) +### Set the universally universal identifiers (UUID) for each variable + +- Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal () - Find and click the white "View Token UUID List" button above the small map on your site page - **VERY CAREFULLY** check that the variables are in exactly the same order as in the variable array: @@ -122,12 +128,12 @@ const char* samplingFeature = "12345678-abcd-1234-ef00-1234567890ab"; // Sampli ``` -## Upload! +### Upload! + - Test everything at home **before** deploying out in the wild! _______ - [//]: # ( @section example_drwi_2g_pio_config PlatformIO Configuration ) [//]: # ( @include{lineno} DRWI_2G/platformio.ini ) diff --git a/examples/DRWI_DigiLTE/ReadMe.md b/examples/DRWI_DigiLTE/ReadMe.md index d101cd724..52ea73215 100644 --- a/examples/DRWI_DigiLTE/ReadMe.md +++ b/examples/DRWI_DigiLTE/ReadMe.md @@ -3,11 +3,11 @@ This example uses the sensors and equipment common to older stations (2016-2020) deployed by groups participating in the DRWI Citizen Science project with the Stroud Water Research Center. It includes a Meter Hydros21 CTD (formerly know as a Decagon), a Campbell OBS3+ (Turbidity), and a Digi XBee3 LTE-M cellular board for communication. The Digi LTE module also required the use of a EnviroDIY LTEbee Adapter board (discontinued in 2021). The Digi LTE modules are no longer recommended for use and have been replace by the EnviroDIY LTEbee in all DRWI-SWRC-managed stations. The exact hardware configuration used in this example: - * Mayfly v0.5b board - * Digi Xbee LTE module (with Hologram SIM card and EnviroDIY bee adapter) - * Hydros21 CTD sensor - * Campbell OBS3+ turbidity sensor +- Mayfly v0.5b board +- Digi XBee LTE module (with Hologram SIM card and EnviroDIY bee adapter) +- Hydros21 CTD sensor +- Campbell OBS3+ turbidity sensor _______ @@ -16,37 +16,43 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [DRWI Digi LTE Sites](#drwi-digi-lte-sites) -- [Unique Features of the DRWI Digi LTE Example](#unique-features-of-the-drwi-digi-lte-example) -- [To Use this Example](#to-use-this-example) - - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) - - [Set the logger ID](#set-the-logger-id) - - [Set the calibration coefficients for the Campbell OBS3+](#set-the-calibration-coefficients-for-the-campbell-obs3) - - [Set the universally universal identifiers (UUID) for each variable](#set-the-universally-universal-identifiers-uuid-for-each-variable) - - [Upload!](#upload) + - [Unique Features of the DRWI Digi LTE Example](#unique-features-of-the-drwi-digi-lte-example) + - [To Use this Example](#to-use-this-example) + - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) + - [Set the logger ID](#set-the-logger-id) + - [Set the calibration coefficients for the Campbell OBS3+](#set-the-calibration-coefficients-for-the-campbell-obs3) + - [Set the universally universal identifiers (UUID) for each variable](#set-the-universally-universal-identifiers-uuid-for-each-variable) + - [Upload!](#upload) [//]: # ( End GitHub Only ) _______ -# Unique Features of the DRWI Digi LTE Example +## Unique Features of the DRWI Digi LTE Example + - Specifically for sites within the Delaware River Watershed Initiative. + - Uses a Digi XBee3 LTE-M for live data. -# To Use this Example +## To Use this Example + +### Prepare and set up PlatformIO + +- Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal () -## Prepare and set up PlatformIO -- Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/DRWI_DigiLTE/platformio.ini) file in the examples/DRWI_DigiLTE folder on GitHub. - - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. - - Without this, the program won't compile. + - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. + - Without this, the program won't compile. - Open [DRWI_DigiLTE.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/DRWI_DigiLTE/DRWI_DigiLTE.ino) and save it to your computer. - - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". - - Move it into the src directory of your project. - - Delete main.cpp in that folder. + - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". + - Move it into the src directory of your project. + - Delete main.cpp in that folder. + +### Set the logger ID -## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -54,12 +60,14 @@ _______ const char *LoggerID = "XXXX"; ``` -## Set the calibration coefficients for the Campbell OBS3+ +### Set the calibration coefficients for the Campbell OBS3+ + - The OBS3+ ships with a calibration certificate; you need this sheet! + - Change _**all**_ of the the `0.000E+00` and `1.000E+00` values in this section of code to the values on that calibration sheet. Use numbers from the side of the calibration sheet that shows the calibration in _**volts**_. - - The sketch will not compile if these values are not entered properly. - - Do not change any values except those that are `0.000E+00` and `1.000E+00`! + - The sketch will not compile if these values are not entered properly. + - Do not change any values except those that are `0.000E+00` and `1.000E+00`! ```cpp // ========================================================================== @@ -83,8 +91,10 @@ const float OBSHigh_C = 0.000E+00; // "C" value [*high* range] CampbellOBS3 osb3high(OBS3Power, OBSHighADSChannel, OBSHigh_A, OBSHigh_B, OBSHigh_C, ADSi2c_addr, OBS3numberReadings); ``` -## Set the universally universal identifiers (UUID) for each variable -- Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) +### Set the universally universal identifiers (UUID) for each variable + +- Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal () + - Find and click the white "View Token UUID List" button above the small map on your site page - **VERY CAREFULLY** check that the variables are in exactly the same order as in the variable array: @@ -122,12 +132,12 @@ const char* samplingFeature = "12345678-abcd-1234-ef00-1234567890ab"; // Sampli ``` -## Upload! +### Upload! + - Test everything at home **before** deploying out in the wild! _______ - [//]: # ( @section example_drwi_digilte_pio_config PlatformIO Configuration ) [//]: # ( @include{lineno} DRWI_DigiLTE/platformio.ini ) diff --git a/examples/DRWI_Mayfly1/ReadMe.md b/examples/DRWI_Mayfly1/ReadMe.md index f814a8b70..65f633b27 100644 --- a/examples/DRWI_Mayfly1/ReadMe.md +++ b/examples/DRWI_Mayfly1/ReadMe.md @@ -1,12 +1,14 @@ # DRWI Sites with a Mayfly 1.x and EnviroDIY LTE Bees + Example sketch for using the EnviroDIY SIM7080G LTE cellular module with an EnviroDIY Mayfly Data Logger. This example uses the sensors and equipment used by most groups participating in the DRWI (Delaware River Watershed Initiative) Citizen Science project with the Stroud Water Research Center. It includes a Meter Hydros 21 (CTD) and a SIM7080G-based EnviroDIY LTEbee for communication. This examples also makes use of the on-board light, temperature, and humidity sensors on the Mayfly 1.x. The results are saved to the SD card and posted to the Monitor My Watershed data portal. Only to be used with newer Mayfly v1.0 and v1.1 boards. The exact hardware configuration used in this example: - * Mayfly v1.x board - * EnviroDIY SIM7080 LTE module (with Hologram SIM card) - * Hydros21 CTD sensor + +- Mayfly v1.x board +- EnviroDIY SIM7080 LTE module (with Hologram SIM card) +- Hydros21 CTD sensor An EnviroDIY LTE SIM7080 module can be used with the older Mayfly v0.5b boards if you change line 101 (for modemVccPin) from 18 to -1. This is because the Mayfly v1.x board has a separate 3.3v regulator to power the Bee socket and is controlled by turning pin 18 on or off. @@ -25,18 +27,19 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [DRWI Sites with a Mayfly 1.x and EnviroDIY LTE Bees](#drwi-sites-with-a-mayfly-1x-and-envirodiy-lte-bees) -- [Unique Features of the DRWI Mayfly 1.x LTE Example](#unique-features-of-the-drwi-mayfly-1x-lte-example) + - [Unique Features of the DRWI Mayfly 1.x LTE Example](#unique-features-of-the-drwi-mayfly-1x-lte-example) [//]: # ( End GitHub Only ) _______ -# Unique Features of the DRWI Mayfly 1.x LTE Example +## Unique Features of the DRWI Mayfly 1.x LTE Example + - Specifically for sites within the Delaware River Watershed Initiative. - Uses a EnviroDIY LTE Bee based on the SIMCom SIM7080G - [//]: # ( @section example_drwi_mayfly1_pio_config PlatformIO Configuration ) [//]: # ( @include{lineno} DRWI_Mayfly1/platformio.ini ) diff --git a/examples/DRWI_Mayfly1_WiFi/ReadMe.md b/examples/DRWI_Mayfly1_WiFi/ReadMe.md index 9641d4c94..6682830ae 100644 --- a/examples/DRWI_Mayfly1_WiFi/ReadMe.md +++ b/examples/DRWI_Mayfly1_WiFi/ReadMe.md @@ -1,10 +1,12 @@ # DRWI Sites with a Mayfly 1.x and EnviroDIY ESP32 WiFi Bees + Example sketch for using the EnviroDIY ESP32 WiFi cellular module with an EnviroDIY Mayfly Data Logger. The exact hardware configuration used in this example: - * Mayfly v1.1 board - * EnviroDIY ESP32 WiFi module - * Hydros21 CTD sensor + +- Mayfly v1.1 board +- EnviroDIY ESP32 WiFi module +- Hydros21 CTD sensor An EnviroDIY ESP32 WiFi module can also be used with the older Mayfly v0.5b boards if you change line 95 (for modemVccPin) from 18 to -1. This is because the Mayfly v1.x board has a separate 3.3v regulator to power the Bee socket and is controlled by turning pin 18 on or off. @@ -21,18 +23,19 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) -- [DRWI Sites with a Mayfly 1.x and EnviroDIY ESP32 WiFi Bees ](#drwi-sites-with-a-mayfly-1x-and-envirodiy-esp32-wifi-bees-) -- [Unique Features of the DRWI Mayfly 1.x WiFi Example ](#unique-features-of-the-drwi-mayfly-1x-wifi-example-) + +- [DRWI Sites with a Mayfly 1.x and EnviroDIY ESP32 WiFi Bees](#drwi-sites-with-a-mayfly-1x-and-envirodiy-esp32-wifi-bees) + - [Unique Features of the DRWI Mayfly 1.x WiFi Example](#unique-features-of-the-drwi-mayfly-1x-wifi-example) [//]: # ( End GitHub Only ) _______ -# Unique Features of the DRWI Mayfly 1.x WiFi Example +## Unique Features of the DRWI Mayfly 1.x WiFi Example + - Specifically for sites within the Delaware River Watershed Initiative. - Uses a EnviroDIY WiFi Bee based on the Espressif ESP32-WROOM-32 - [//]: # ( @section example_drwi_mayfly1_wifi_pio_config PlatformIO Configuration ) [//]: # ( @include{lineno} DRWI_Mayfly1_WiFi/platformio.ini ) diff --git a/examples/DRWI_NoCellular/ReadMe.md b/examples/DRWI_NoCellular/ReadMe.md index 9ca23963e..5f627ecf7 100644 --- a/examples/DRWI_NoCellular/ReadMe.md +++ b/examples/DRWI_NoCellular/ReadMe.md @@ -4,12 +4,12 @@ This is the code example that should be used for all groups working with the Str This example should be used in cases where no cellular service of any kind is available and the data will only be logged on the SD card. The exact hardware configuration used in this example: - * Mayfly v1.x board - * Hydros21 CTD sensor - * Campbell OBS3+ turbidity sensor +- Mayfly v1.x board +- Hydros21 CTD sensor +- Campbell OBS3+ turbidity sensor -Before using this example, you must register a site and sensors at the data portal (http://data.envirodiy.org/). +Before using this example, you must register a site and sensors at the data portal (). After you have registered the site and sensors, the portal will generate a registration token and universally unique identifier (UUID) for each site and further UUID's for each variable. You will need to copy all of those UUID values into your sketch to replace the `12345678-abcd-1234-ef00-1234567890ab` place holders in this example. __You should register even if your logger will not be sending live data.__ This ensures that the data file your logger writes will be ready to immediately upload to the portal. @@ -21,37 +21,41 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [DRWI sites with no Cellular Service](#drwi-sites-with-no-cellular-service) -- [Unique Features of the DRWI LTE Example](#unique-features-of-the-drwi-lte-example) -- [To Use this Example](#to-use-this-example) - - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) - - [Set the logger ID](#set-the-logger-id) - - [Set the calibration coefficients for the Campbell OBS3+](#set-the-calibration-coefficients-for-the-campbell-obs3) - - [Set the universally universal identifiers (UUID) for each variable](#set-the-universally-universal-identifiers-uuid-for-each-variable) - - [Upload!](#upload) + - [Unique Features of the DRWI LTE Example](#unique-features-of-the-drwi-lte-example) + - [To Use this Example](#to-use-this-example) + - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) + - [Set the logger ID](#set-the-logger-id) + - [Set the calibration coefficients for the Campbell OBS3+](#set-the-calibration-coefficients-for-the-campbell-obs3) + - [Set the universally universal identifiers (UUID) for each variable](#set-the-universally-universal-identifiers-uuid-for-each-variable) + - [Upload!](#upload) [//]: # ( End GitHub Only ) _______ -# Unique Features of the DRWI LTE Example +## Unique Features of the DRWI LTE Example + - Specifically for sites within the Delaware River Watershed Initiative. - Does *not* include any live data uploads. -# To Use this Example +## To Use this Example -## Prepare and set up PlatformIO -- Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) +### Prepare and set up PlatformIO + +- Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal () - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/DRWI_NoCellular/platformio.ini) file in the examples/DRWI_NoCellular folder on GitHub. - - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. - - Without this, the program won't compile. + - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. + - Without this, the program won't compile. - Open [DRWI_NoCellular.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/DRWI_NoCellular/DRWI_NoCellular.ino) and save it to your computer. - - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". - - Move it into the src directory of your project. - - Delete main.cpp in that folder. + - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". + - Move it into the src directory of your project. + - Delete main.cpp in that folder. + +### Set the logger ID -## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -59,12 +63,13 @@ _______ const char *LoggerID = "XXXX"; ``` -## Set the calibration coefficients for the Campbell OBS3+ +### Set the calibration coefficients for the Campbell OBS3+ + - The OBS3+ ships with a calibration certificate; you need this sheet! -- Change _**all**_ of the the `0.000E+00` and `1.000E+00` values in this section of code to the values on that calibration sheet. -Use numbers from the side of the calibration sheet that shows the calibration in _**volts**_. - - The sketch will not compile if these values are not entered properly. - - Do not change any values except those that are `0.000E+00` and `1.000E+00`! +- Change *__all__* of the the `0.000E+00` and `1.000E+00` values in this section of code to the values on that calibration sheet. +Use numbers from the side of the calibration sheet that shows the calibration in *__volts__*. + - The sketch will not compile if these values are not entered properly. + - Do not change any values except those that are `0.000E+00` and `1.000E+00`! ```cpp // ========================================================================== @@ -88,10 +93,11 @@ const float OBSHigh_C = 0.000E+00; // "C" value [*high* range] CampbellOBS3 osb3high(OBS3Power, OBSHighADSChannel, OBSHigh_A, OBSHigh_B, OBSHigh_C, ADSi2c_addr, OBS3numberReadings); ``` -## Set the universally universal identifiers (UUID) for each variable -- Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) +### Set the universally universal identifiers (UUID) for each variable + +- Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal () - Find and click the white "View Token UUID List" button above the small map on your site page -- **VERY CAREFULLY** check that the variables are in exactly the same order as in the variable array: +- __VERY CAREFULLY__ check that the variables are in exactly the same order as in the variable array: ```cpp Variable* variableList[] = { @@ -99,7 +105,7 @@ Variable* variableList[] = { } ``` -- If any of the variables are in a different order on the web page than in your code **reorder the variables in your code to match the website**. +- If any of the variables are in a different order on the web page than in your code __reorder the variables in your code to match the website__. - After you are completely certain that you have the order right in the variable section of your code use the teal "Copy" button on the website to copy the section of code containing all of the UUID's. - Paste the code from the website into your program in this section below the variable array @@ -125,11 +131,11 @@ const char* samplingFeature = "12345678-abcd-1234-ef00-1234567890ab"; // Sampli ``` -## Upload! -- Test everything at home **before** deploying out in the wild! +### Upload! -_______ +- Test everything at home __before__ deploying out in the wild! +_______ [//]: # ( @section example_drwi_no_cell_pio_config PlatformIO Configuration ) diff --git a/examples/DRWI_SIM7080LTE/ReadMe.md b/examples/DRWI_SIM7080LTE/ReadMe.md index b3a610ee0..f2192d9ce 100644 --- a/examples/DRWI_SIM7080LTE/ReadMe.md +++ b/examples/DRWI_SIM7080LTE/ReadMe.md @@ -3,10 +3,11 @@ The DRWI EnviroDIY LTEbee example uses the sensors and equipment common to older stations (2016-2020) deployed by groups participating in the DRWI Citizen Science project with the Stroud Water Research Center. It includes a Meter Hydros 21 (CTD), a Campbell OBS3+, (Turbidity) and a SIM7080G-based EnviroDIY LTEbee for communication. The exact hardware configuration used in this example: - * Mayfly v1.x board - * EnviroDIY SIM7080 LTE module (with Hologram SIM card) - * Hydros21 CTD sensor - * Campbell Scientific OBS3+ Turbidity sensor + +- Mayfly v1.x board +- EnviroDIY SIM7080 LTE module (with Hologram SIM card) +- Hydros21 CTD sensor +- Campbell Scientific OBS3+ Turbidity sensor An EnviroDIY LTE SIM7080 module can be used with the older Mayfly v0.5b boards if you change line 101 (for modemVccPin) from 18 to -1. This is because the Mayfly v1.0 board has a separate 3.3v regulator to power the Bee socket and is controlled by turning pin 18 on or off. @@ -24,18 +25,19 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [DRWI Sites with EnviroDIY LTE Bees](#drwi-sites-with-envirodiy-lte-bees) -- [Unique Features of the DRWI EnviroDIY LTE Example](#unique-features-of-the-drwi-envirodiy-lte-example) + - [Unique Features of the DRWI EnviroDIY LTE Example](#unique-features-of-the-drwi-envirodiy-lte-example) [//]: # ( End GitHub Only ) _______ -# Unique Features of the DRWI EnviroDIY LTE Example +## Unique Features of the DRWI EnviroDIY LTE Example + - Specifically for sites within the Delaware River Watershed Initiative. - Uses a EnviroDIY LTE Bee based on the SIMCom SIM7080G - [//]: # ( @section example_drwi_ediylte_pio_config PlatformIO Configuration ) [//]: # ( @include{lineno} DRWI_SIM7080LTE/platformio.ini ) diff --git a/examples/ReadMe.md b/examples/ReadMe.md index 0a2801fea..f12f86840 100644 --- a/examples/ReadMe.md +++ b/examples/ReadMe.md @@ -6,6 +6,7 @@ Each example has slightly different functionality. ___ [//]: # ( Start GitHub Only ) + - [Examples Using ModularSensors](#examples-using-modularsensors) - [Basic Functionality](#basic-functionality) - [Single Sensor](#single-sensor) @@ -20,7 +21,7 @@ ___ - [Minimizing Cell Data Usage](#minimizing-cell-data-usage) - [DRWI Citizen Science](#drwi-citizen-science) - [DRWI Mayfly 1.x LTE](#drwi-mayfly-1x-lte) - - [DRWI EnviroDIY Bee LTE](#drwi-envirodiy-bee-lte) + - [DRWI EnviroDIY LTEbee](#drwi-envirodiy-ltebee) - [DRWI Digi LTE](#drwi-digi-lte) - [DRWI CitSci (2G)](#drwi-citsci-2g) - [DRWI CitSci No Cellular](#drwi-citsci-no-cellular) @@ -43,7 +44,6 @@ It also shows creating a calculated variable which is the water depth. - [Instructions for the single sensor example](https://envirodiy.github.io/ModularSensors/example_single_sensor.html) - [The single sensor example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/single_sensor) - ### Simple Logging The simple logging example shows how to create multiple sensors, create variables for the sensors in a variable array, and log the data from the sensors to an SD card. @@ -51,7 +51,6 @@ The simple logging example shows how to create multiple sensors, create variable - [Instructions for the simple logging example](https://envirodiy.github.io/ModularSensors/example_simple_logging.html) - [The simple logging example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/simple_logging) - ### Simple Logging for the Learn EnviroDIY course The simple logging example for the [Learn EnviroDIY programming course](https://envirodiy.github.io/LearnEnviroDIY/) shows how to create multiple sensors, create variables for the sensors in a variable array, and log the data from the sensors to an SD card. @@ -60,7 +59,6 @@ It is very similar to the other simple logging example, with just a few extra se - [Instructions for the learn EnviroDIY course example](https://envirodiy.github.io/ModularSensors/example_learn_envirodiy.html) - [The learn EnviroDIY course example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/simple_logging_LearnEnviroDIY) - ___ ## Publishing Data @@ -72,7 +70,6 @@ The logging to Monitor My Watershed example uses a Digi XBee in transparent mode - [Instructions for the logging to Monitor My Watershed example](https://envirodiy.github.io/ModularSensors/example_mmw.html) - [The logging to Monitor My Watershed example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/logging_to_MMW) - ### Publishing to ThingSpeak The logging to ThingSpeak example uses an ESP8266 to send data to ThingSpeak. @@ -81,7 +78,6 @@ It also includes a Meter Hydros 21 (formerly know as a Decagon CTD) and a Campbe - [Instructions for the logging to ThingSpeak example](https://envirodiy.github.io/ModularSensors/example_thingspeak.html) - [The logging to ThingSpeak example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/logging_to_ThingSpeak) - ___ ## Calculations and Complex Logging @@ -93,7 +89,6 @@ The barometric pressure correction example demonstrates how to work with calcul - [Instructions for the barometric pressure correction example](https://envirodiy.github.io/ModularSensors/example_baro_rho.html) - [The barometric pressure correction example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/baro_rho_correction) - ### Multiple Logging Intervals The more complicated double logger example using two different logger instances to log data at two different intervals, in this case, an AM3215 logging every minute, while checking the battery voltage only every 5 minutes. @@ -102,8 +97,7 @@ This showcases both how to use two different logging instances and how to use so - [Instructions for the double logger example](https://envirodiy.github.io/ModularSensors/example_double_log.html) - [The double logger example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/double_logger) - -### Minimizing Cell Data Usage +### Minimizing Cell Data Usage The data saving example is another double logger example, but in this case, both loggers are going at the same interval and the only difference between the loggers is the list of variables. There are two sets of variables, all coming from Yosemitech sensors. @@ -113,7 +107,6 @@ This example also shows how to stop power draw from an RS485 adapter with automa - [Instructions for the data saving example](https://envirodiy.github.io/ModularSensors/example_data_saving.html) - [The data saving example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/data_saving) - ___ ## DRWI Citizen Science @@ -148,7 +141,6 @@ The only difference between this and the other cellular DRWI examples is the typ - [Instructions for the Digi LTE DRWI Citizen Science example](https://envirodiy.github.io/ModularSensors/example_drwi_digilte.html) - [The Digi LTE DRWI Citizen Science example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/DRWI_DigiLTE) - ### DRWI CitSci (2G) The 2G DRWI Citizen Science example uses the sensors and equipment found on older stations used in the DRWI Citizen Science project prior to 2020. The 2G GPRSbee boards no longer function in the USA, so this code should not be used and is only provided to archival and reference purposes. @@ -159,7 +151,6 @@ The only difference between this and the other cellular DRWI examples is the typ - [Instructions for the 2G DRWI Citizen Science example](https://envirodiy.github.io/ModularSensors/example_drwi_2g.html) - [The 2G DRWI Citizen Science example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/DRWI_CitSci) - ### DRWI CitSci No Cellular The DRWI no cellular example uses the sensors and equipment standard to the DRWI Citizen Science project but omits the data publisher for circumstances where there is no cellular signal. @@ -169,7 +160,6 @@ The exclusion of the modem and publisher simplifies the code from the other DRWI - [Instructions for the no-cellular DRWI Citizen Science example](https://envirodiy.github.io/ModularSensors/example_drwi_no_cell.html) - [The no-cellular DRWI Citizen Science example on GitHub](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/DRWI_NoCellular) - ___ ## Everything at Once - a la carte diff --git a/examples/baro_rho_correction/ReadMe.md b/examples/baro_rho_correction/ReadMe.md index eb37c6e60..828857f82 100644 --- a/examples/baro_rho_correction/ReadMe.md +++ b/examples/baro_rho_correction/ReadMe.md @@ -13,36 +13,40 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [Calculating Results based on Measured Values](#calculating-results-based-on-measured-values) -- [Unique Features of the Barometric Correction Example](#unique-features-of-the-barometric-correction-example) -- [To Use this Example](#to-use-this-example) - - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) - - [Set the logger ID](#set-the-logger-id) - - [Set the universally universal identifiers (UUID) for each variable](#set-the-universally-universal-identifiers-uuid-for-each-variable) - - [Upload!](#upload) + - [Unique Features of the Barometric Correction Example](#unique-features-of-the-barometric-correction-example) + - [To Use this Example](#to-use-this-example) + - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) + - [Set the logger ID](#set-the-logger-id) + - [Set the universally universal identifiers (UUID) for each variable](#set-the-universally-universal-identifiers-uuid-for-each-variable) + - [Upload!](#upload) [//]: # ( End GitHub Only ) _______ -# Unique Features of the Barometric Correction Example +## Unique Features of the Barometric Correction Example + - All variables are created and named with their parent sensor (as opposed to being created within the variable array). - There are multiple calculated variables created and used. -# To Use this Example +## To Use this Example + +### Prepare and set up PlatformIO -## Prepare and set up PlatformIO -- Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) +- Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal () - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/baro_rho_correction/platformio.ini) file in the examples/baro_rho_correction folder on GitHub. - - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. - - Without this, the program won't compile. + - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. + - Without this, the program won't compile. - Open [baro_rho_correction.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/baro_rho_correction/baro_rho_correction.ino) and save it to your computer. - - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". - - Move it into the src directory of your project. - - Delete main.cpp in that folder. + - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". + - Move it into the src directory of your project. + - Delete main.cpp in that folder. + +### Set the logger ID -## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -50,11 +54,13 @@ _______ const char *LoggerID = "XXXX"; ``` -## Set the universally universal identifiers (UUID) for each variable -- Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) +### Set the universally universal identifiers (UUID) for each variable + +- Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal () - For each variable, find the dummy UUID (`"12345678-abcd-1234-ef00-1234567890ab"`) and replace it with the real UUID for the variable. -## Upload! +### Upload! + - Test everything at home **before** deploying out in the wild! _______ diff --git a/examples/data_saving/ReadMe.md b/examples/data_saving/ReadMe.md index b689fdd16..86abbdeaa 100644 --- a/examples/data_saving/ReadMe.md +++ b/examples/data_saving/ReadMe.md @@ -15,19 +15,21 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [Minimizing Cellular Data Use](#minimizing-cellular-data-use) -- [Unique Features of the Data Saving Example](#unique-features-of-the-data-saving-example) -- [To Use this Example](#to-use-this-example) - - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) - - [Set the logger ID](#set-the-logger-id) - - [Set the universally universal identifiers (UUID) for each variable](#set-the-universally-universal-identifiers-uuid-for-each-variable) - - [Upload!](#upload) + - [Unique Features of the Data Saving Example](#unique-features-of-the-data-saving-example) + - [To Use this Example](#to-use-this-example) + - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) + - [Set the logger ID](#set-the-logger-id) + - [Set the universally universal identifiers (UUID) for each variable](#set-the-universally-universal-identifiers-uuid-for-each-variable) + - [Upload!](#upload) [//]: # ( End GitHub Only ) _______ -# Unique Features of the Data Saving Example +## Unique Features of the Data Saving Example + - Uses AltSoftSerial to create an additional serial port for RS485 communication. - All variables are created and named with their parent sensor (as opposed to being created within the variable array). - Two different variable arrays and loggers are created and used. @@ -37,20 +39,22 @@ _______ - This demonstrates *how* to write the loop out, without using the `logData` functions. - It also shows how to forcibly set serial pins `LOW` at the start and end of the loop in order to prevent power loss through an RS485 adapter. -# To Use this Example +## To Use this Example -## Prepare and set up PlatformIO -- Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) +### Prepare and set up PlatformIO + +- Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal () - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/data_saving/platformio.ini) file in the examples/data_saving folder on GitHub. - - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. - - Without this, the program won't compile. + - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. + - Without this, the program won't compile. - Open [data_saving.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/data_saving/data_saving.ino) and save it to your computer. - - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". - - Move it into the src directory of your project. - - Delete main.cpp in that folder. + - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". + - Move it into the src directory of your project. + - Delete main.cpp in that folder. + +### Set the logger ID -## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -58,16 +62,17 @@ _______ const char *LoggerID = "XXXX"; ``` -## Set the universally universal identifiers (UUID) for each variable -- Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) +### Set the universally universal identifiers (UUID) for each variable + +- Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal () - For each variable, find the dummy UUID (`"12345678-abcd-1234-ef00-1234567890ab"`) and replace it with the real UUID for the variable. -## Upload! +### Upload! + - Test everything at home **before** deploying out in the wild! _______ - [//]: # ( @section example_data_saving_pio_config PlatformIO Configuration ) [//]: # ( @include{lineno} data_saving/platformio.ini ) diff --git a/examples/double_logger/ReadMe.md b/examples/double_logger/ReadMe.md index c22e20160..8f839cee4 100644 --- a/examples/double_logger/ReadMe.md +++ b/examples/double_logger/ReadMe.md @@ -10,18 +10,20 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [Multiple Time Intervals](#multiple-time-intervals) -- [Unique Features of the Double Logger Example](#unique-features-of-the-double-logger-example) -- [To Use this Example](#to-use-this-example) - - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) - - [Set the logger ID](#set-the-logger-id) - - [Upload!](#upload) + - [Unique Features of the Double Logger Example](#unique-features-of-the-double-logger-example) + - [To Use this Example](#to-use-this-example) + - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) + - [Set the logger ID](#set-the-logger-id) + - [Upload!](#upload) [//]: # ( End GitHub Only ) _______ -# Unique Features of the Double Logger Example +## Unique Features of the Double Logger Example + - Two different variable arrays and loggers are created and used. - The Variables for the arrays are created within the array. - There is no variable overlap between the two arrays or loggers. @@ -29,19 +31,21 @@ _______ - This demonstrates *how* to write the loop out, without using the `logData` functions. - This shows which functions are required for each of the two loggers and which can be used in common. -# To Use this Example +## To Use this Example + +### Prepare and set up PlatformIO -## Prepare and set up PlatformIO - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/double_logger/platformio.ini) file in the examples/double_logger folder on GitHub. - - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. - - Without this, the program won't compile. + - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. + - Without this, the program won't compile. - Open [double_logger.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/double_logger/double_logger.ino) and save it to your computer. - - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". - - Move it into the src directory of your project. - - Delete main.cpp in that folder. + - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". + - Move it into the src directory of your project. + - Delete main.cpp in that folder. + +### Set the logger ID -## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -49,12 +53,12 @@ _______ const char *LoggerID = "XXXX"; ``` -## Upload! +### Upload! + - Test everything at home **before** deploying out in the wild! _______ - [//]: # ( @section example_double_log_pio_config PlatformIO Configuration ) [//]: # ( @include{lineno} double_logger/platformio.ini ) diff --git a/examples/logging_to_MMW/ReadMe.md b/examples/logging_to_MMW/ReadMe.md index c7e6d4398..daad6686c 100644 --- a/examples/logging_to_MMW/ReadMe.md +++ b/examples/logging_to_MMW/ReadMe.md @@ -1,6 +1,6 @@ # Sending Data to Monitor My Watershed/EnviroDIY -This sketch reduces menu_a_la_carte.ino to provide an example of how to log to https://monitormywatershed.org/ from two sensors, the BME280 and DS18. To complete the set up for logging to the web portal, the UUIDs for the site and each variable would need to be added to the sketch. +This sketch reduces menu_a_la_carte.ino to provide an example of how to log to from two sensors, the BME280 and DS18. To complete the set up for logging to the web portal, the UUIDs for the site and each variable would need to be added to the sketch. The settings for other data portals were removed from the example. @@ -15,36 +15,40 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [Sending Data to Monitor My Watershed/EnviroDIY](#sending-data-to-monitor-my-watershedenvirodiy) -- [Unique Features of the Monitor My Watershed Example](#unique-features-of-the-monitor-my-watershed-example) -- [To Use this Example](#to-use-this-example) - - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) - - [Set the logger ID](#set-the-logger-id) - - [Set the universally universal identifiers (UUID) for each variable](#set-the-universally-universal-identifiers-uuid-for-each-variable) - - [Upload!](#upload) + - [Unique Features of the Monitor My Watershed Example](#unique-features-of-the-monitor-my-watershed-example) + - [To Use this Example](#to-use-this-example) + - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) + - [Set the logger ID](#set-the-logger-id) + - [Set the universally universal identifiers (UUID) for each variable](#set-the-universally-universal-identifiers-uuid-for-each-variable) + - [Upload!](#upload) [//]: # ( End GitHub Only ) _______ -# Unique Features of the Monitor My Watershed Example +## Unique Features of the Monitor My Watershed Example + - A single logger publishes data to the Monitor My Watershed data portal. - Uses a cellular Digi XBee or XBee3 -# To Use this Example +## To Use this Example + +### Prepare and set up PlatformIO -## Prepare and set up PlatformIO -- Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) +- Register a site and sensors at the Monitor My Watershed/EnviroDIY data portal () - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/logging_to_MMW/platformio.ini) file in the examples/logging_to_MMW folder on GitHub. - - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. - - Without this, the program won't compile. + - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. + - Without this, the program won't compile. - Open [logging_to_MMW.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/logging_to_MMW/logging_to_MMW.ino) and save it to your computer. - - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". - - Move it into the src directory of your project. - - Delete main.cpp in that folder. + - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". + - Move it into the src directory of your project. + - Delete main.cpp in that folder. + +### Set the logger ID -## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -52,11 +56,13 @@ _______ const char *LoggerID = "XXXX"; ``` -## Set the universally universal identifiers (UUID) for each variable -- Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal (http://monitormywatershed.org/) +### Set the universally universal identifiers (UUID) for each variable + +- Go back to the web page for your site at the Monitor My Watershed/EnviroDIY data portal () - For each variable, find the dummy UUID (`"12345678-abcd-1234-ef00-1234567890ab"`) and replace it with the real UUID for the variable. -## Upload! +### Upload! + - Test everything at home **before** deploying out in the wild! _______ diff --git a/examples/logging_to_ThingSpeak/ReadMe.md b/examples/logging_to_ThingSpeak/ReadMe.md index a6d51e31b..1ae9105e9 100644 --- a/examples/logging_to_ThingSpeak/ReadMe.md +++ b/examples/logging_to_ThingSpeak/ReadMe.md @@ -10,50 +10,54 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [Sending data to ThingSpeak](#sending-data-to-thingspeak) -- [Unique Features of the ThingSpeak Example](#unique-features-of-the-thingspeak-example) -- [To Use this Example](#to-use-this-example) - - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) - - [Modify the Example](#modify-the-example) - - [Upload!](#upload) + - [Unique Features of the ThingSpeak Example](#unique-features-of-the-thingspeak-example) + - [To Use this Example](#to-use-this-example) + - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) + - [Modify the Example](#modify-the-example) + - [Upload!](#upload) [//]: # ( End GitHub Only ) _______ -# Unique Features of the ThingSpeak Example +## Unique Features of the ThingSpeak Example + - A single logger publishes data to ThingSpeak. - Uses an Espressif ESP8266 to publish data. -# To Use this Example +## To Use this Example + +### Prepare and set up PlatformIO -## Prepare and set up PlatformIO - Create a channel on ThingSpeak with fields to receive your data. - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/logging_to_ThingSpeak/platformio.ini) file in the examples/logging_to_ThingSpeak folder on GitHub. - - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. - - Without this, the program won't compile. + - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. + - Without this, the program won't compile. - Open [logging_to_ThingSpeak.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/logging_to_ThingSpeak/logging_to_ThingSpeak.ino) and save it to your computer. - - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". - - Move it into the src directory of your project. - - Delete main.cpp in that folder. + - After opening the link, you should be able to right click anywhere on the page and select "Save Page As". + - Move it into the src directory of your project. + - Delete main.cpp in that folder. + +### Modify the Example -## Modify the Example - Modify logging_to_ThingSpeak.ino to have the modem, sensor, and variable objects that you are interested in. - - This example is written for an _ESP8266 (wifi)_ modem. + - This example is written for an _ESP8266 (wifi)_ modem. Change this to whatever modem you are using. Pastable chunks of code for each modem are available in the individual sensor documentation or in the menu a la carte example. - - Don't forget to put in your wifi username/password or cellular APN! - - This example is written for a Campbell OBS3+ and a Meter Hydros 21. + - Don't forget to put in your wifi username/password or cellular APN! + - This example is written for a Campbell OBS3+ and a Meter Hydros 21. Remove those sensors if you are not using them and add code for all of your sensors. See the pages for the individual sensors in the [documentation](https://envirodiy.github.io/ModularSensors/index.html) for code snippets/examples. - - Remember, no more than **8** variables/fields can be sent to a single ThingSpeak channel. + - Remember, no more than **8** variables/fields can be sent to a single ThingSpeak channel. If you want to send data to multiple channels, you must create individual logger objects with unique publishers attached for each channel you want to send to. - **Make sure the pin numbers and serial ports selected in your code match with how things are physically attached to your board!** - Order the variables in your variable array in the same order as your fields are on ThingSpeak. - - This order is __crucial__. + - This order is **crucial**. The results from the variables in the VariableArray will be sent to ThingSpeak in the order they are in the array; that is, the first variable in the array will be sent as Field1, the second as Field2, etc. - - Any UUID's or custom variable codes are ignored for ThingSpeak. + - Any UUID's or custom variable codes are ignored for ThingSpeak. They will only appear in the header of your file on the SD card. - Find this information for your ThingSpeak account and channel and put it into logging_to_ThingSpeak.ino: @@ -63,12 +67,12 @@ const char *thingSpeakChannelID = "######"; // The numeric channel id for your const char *thingSpeakChannelKey = "XXXXXXXXXXXXXXXX"; // The Write API Key for your channel ``` -## Upload! +### Upload! + - Test everything at home **before** deploying out in the wild! _______ - [//]: # ( @section example_thingspeak_pio_config PlatformIO Configuration ) [//]: # ( @include{lineno} logging_to_ThingSpeak/platformio.ini ) diff --git a/examples/menu_a_la_carte/ReadMe.md b/examples/menu_a_la_carte/ReadMe.md index f27f268d9..b8e1cb3fd 100644 --- a/examples/menu_a_la_carte/ReadMe.md +++ b/examples/menu_a_la_carte/ReadMe.md @@ -6,12 +6,12 @@ This example should *never* be used directly; it is intended to document all pos To create your own code, I recommend starting from a much simpler targeted example, like the [Logging to MMW](https://github.com/EnviroDIY/ModularSensors/tree/master/examples/logging_to_MMW) example, and then adding to it based on only the parts of this menu example that apply to you. -_______ +___ # Walking Through the Code [//]: # ( @note ) -*NOTE: This walkthrough is intended to be viewed on GitHub pages at https://envirodiy.github.io/ModularSensors/example_menu.html* +*NOTE: This walkthrough is intended to be viewed on GitHub pages at * [//]: # ( @warning ) WARNING: This example is long. @@ -24,139 +24,140 @@ ___ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) -- [Example showing all possible functionality ](#example-showing-all-possible-functionality-) -- [Walking Through the Code ](#walking-through-the-code-) - - [Defines and Includes ](#defines-and-includes-) - - [Defines for the Arduino IDE ](#defines-for-the-arduino-ide-) - - [Library Includes ](#library-includes-) - - [Logger Settings ](#logger-settings-) - - [Creating Extra Serial Ports ](#creating-extra-serial-ports-) - - [AVR Boards ](#avr-boards-) - - [AltSoftSerial ](#altsoftserial-) - - [NeoSWSerial ](#neoswserial-) - - [SoftwareSerial with External Interrupts ](#softwareserial-with-external-interrupts-) - - [Software I2C/Wire ](#software-i2cwire-) - - [SAMD Boards ](#samd-boards-) - - [Assigning Serial Port Functionality ](#assigning-serial-port-functionality-) - - [Logging Options ](#logging-options-) - - [Wifi/Cellular Modem Options ](#wificellular-modem-options-) - - [Digi XBee Cellular - Transparent Mode ](#digi-xbee-cellular---transparent-mode-) - - [Digi XBee3 LTE-M - Bypass Mode ](#digi-xbee3-lte-m---bypass-mode-) - - [Digi XBee 3G - Bypass Mode ](#digi-xbee-3g---bypass-mode-) - - [Digi XBee S6B Wifi ](#digi-xbee-s6b-wifi-) - - [Espressif ESP8266 ](#espressif-esp8266-) - - [Quectel BG96 ](#quectel-bg96-) - - [Sequans Monarch ](#sequans-monarch-) - - [SIMCom SIM800 ](#simcom-sim800-) - - [SIMCom SIM7000 ](#simcom-sim7000-) - - [SIMCom SIM7080G (EnviroDIY LTE Bee\]) ](#simcom-sim7080g-envirodiy-lte-bee-) - - [Sodaq GPRSBee ](#sodaq-gprsbee-) - - [u-blox SARA R410M ](#u-blox-sara-r410m-) - - [u-blox SARA U201 ](#u-blox-sara-u201-) - - [Modem Measured Variables ](#modem-measured-variables-) - - [Sensors and Measured Variables ](#sensors-and-measured-variables-) - - [The processor as a sensor ](#the-processor-as-a-sensor-) - - [Maxim DS3231 RTC as a sensor ](#maxim-ds3231-rtc-as-a-sensor-) - - [AOSong AM2315 ](#aosong-am2315-) - - [AOSong DHT ](#aosong-dht-) - - [Apogee SQ-212 Quantum Light Sensor ](#apogee-sq-212-quantum-light-sensor-) - - [Atlas Scientific EZO Circuits ](#atlas-scientific-ezo-circuits-) - - [Atlas Scientific EZO-CO2 Embedded NDIR Carbon Dioxide Sensor ](#atlas-scientific-ezo-co2-embedded-ndir-carbon-dioxide-sensor-) - - [Atlas Scientific EZO-DO Dissolved Oxygen Sensor ](#atlas-scientific-ezo-do-dissolved-oxygen-sensor-) - - [Atlas Scientific EZO-ORP Oxidation/Reduction Potential Sensor ](#atlas-scientific-ezo-orp-oxidationreduction-potential-sensor-) - - [Atlas Scientific EZO-pH Sensor ](#atlas-scientific-ezo-ph-sensor-) - - [Atlas Scientific EZO-RTD Temperature Sensor ](#atlas-scientific-ezo-rtd-temperature-sensor-) - - [Atlas Scientific EZO-EC Conductivity Sensor ](#atlas-scientific-ezo-ec-conductivity-sensor-) - - [Bosch BME280 Environmental Sensor ](#bosch-bme280-environmental-sensor-) - - [Bosch BMP388 and BMP398 Pressure Sensors ](#bosch-bmp388-and-bmp398-pressure-sensors-) - - [Campbell ClariVUE SDI-12 Turbidity Sensor ](#campbell-clarivue-sdi-12-turbidity-sensor-) - - [Campbell OBS3+ Analog Turbidity Sensor ](#campbell-obs3-analog-turbidity-sensor-) - - [Campbell RainVUE SDI-12 Precipitation Sensor ](#campbell-rainvue-sdi-12-precipitation-sensor-) - - [Decagon CTD-10 Conductivity, Temperature, and Depth Sensor ](#decagon-ctd-10-conductivity-temperature-and-depth-sensor-) - - [Decagon ES2 Conductivity and Temperature Sensor ](#decagon-es2-conductivity-and-temperature-sensor-) - - [Everlight ALS-PT19 Ambient Light Sensor ](#everlight-als-pt19-ambient-light-sensor-) - - [External Voltage via TI ADS1x15 ](#external-voltage-via-ti-ads1x15-) - - [Freescale Semiconductor MPL115A2 Miniature I2C Digital Barometer ](#freescale-semiconductor-mpl115a2-miniature-i2c-digital-barometer-) - - [GroPoint Profile GPLP-8 Eight-Segment Soil Moisture and Temperature Profiling Probe ](#gropoint-profile-gplp-8-eight-segment-soil-moisture-and-temperature-profiling-probe-) - - [In-Situ Aqua/Level TROLL Pressure, Temperature, and Depth Sensor ](#in-situ-aqualevel-troll-pressure-temperature-and-depth-sensor-) - - [In-Situ RDO PRO-X Rugged Dissolved Oxygen Probe ](#in-situ-rdo-pro-x-rugged-dissolved-oxygen-probe-) - - [Keller RS485/Modbus Water Level Sensors ](#keller-rs485modbus-water-level-sensors-) - - [Keller Acculevel High Accuracy Submersible Level Transmitter ](#keller-acculevel-high-accuracy-submersible-level-transmitter-) - - [Keller Nanolevel Level Transmitter ](#keller-nanolevel-level-transmitter-) - - [Maxbotix HRXL Ultrasonic Range Finder ](#maxbotix-hrxl-ultrasonic-range-finder-) - - [Maxim DS18 One Wire Temperature Sensor ](#maxim-ds18-one-wire-temperature-sensor-) - - [Measurement Specialties MS5803-14BA Pressure Sensor ](#measurement-specialties-ms5803-14ba-pressure-sensor-) - - [Meter SDI-12 Sensors ](#meter-sdi-12-sensors-) - - [Meter ECH2O Soil Moisture Sensor ](#meter-ech2o-soil-moisture-sensor-) - - [Meter Hydros 21 Conductivity, Temperature, and Depth Sensor ](#meter-hydros-21-conductivity-temperature-and-depth-sensor-) - - [Meter Teros 11 Soil Moisture Sensor ](#meter-teros-11-soil-moisture-sensor-) - - [PaleoTerra Redox Sensors ](#paleoterra-redox-sensors-) - - [Trinket-Based Tipping Bucket Rain Gauge ](#trinket-based-tipping-bucket-rain-gauge-) - - [Sensirion SHT4X Digital Humidity and Temperature Sensor ](#sensirion-sht4x-digital-humidity-and-temperature-sensor-) - - [Northern Widget Tally Event Counter ](#northern-widget-tally-event-counter-) - - [TI INA219 High Side Current Sensor ](#ti-ina219-high-side-current-sensor-) - - [Turner Cyclops-7F Submersible Fluorometer ](#turner-cyclops-7f-submersible-fluorometer-) - - [Analog Electrical Conductivity using the Processor's Analog Pins ](#analog-electrical-conductivity-using-the-processors-analog-pins-) - - [VEGA VEGA PULS 21 ](#vega-vega-puls-21-) - - [Yosemitech RS485/Modbus Environmental Sensors ](#yosemitech-rs485modbus-environmental-sensors-) - - [Yosemitech Y504 Dissolved Oxygen Sensor ](#yosemitech-y504-dissolved-oxygen-sensor-) - - [Yosemitech Y510 Turbidity Sensor ](#yosemitech-y510-turbidity-sensor-) - - [Yosemitech Y511 Turbidity Sensor with Wiper ](#yosemitech-y511-turbidity-sensor-with-wiper-) - - [Yosemitech Y514 Chlorophyll Sensor ](#yosemitech-y514-chlorophyll-sensor-) - - [Yosemitech Y520 Conductivity Sensor ](#yosemitech-y520-conductivity-sensor-) - - [Yosemitech Y532 pH Sensor ](#yosemitech-y532-ph-sensor-) - - [Yosemitech Y533 Oxidation Reduction Potential (ORP) Sensor ](#yosemitech-y533-oxidation-reduction-potential-orp-sensor-) - - [Yosemitech Y551 Carbon Oxygen Demand (COD) Sensor with Wiper ](#yosemitech-y551-carbon-oxygen-demand-cod-sensor-with-wiper-) - - [Yosemitech Y560 Ammonium Sensor ](#yosemitech-y560-ammonium-sensor-) - - [Yosemitech Y700 Pressure Sensor ](#yosemitech-y700-pressure-sensor-) - - [Yosemitech Y4000 Multi-Parameter Sonde ](#yosemitech-y4000-multi-parameter-sonde-) - - [Zebra Tech D-Opto Dissolved Oxygen Sensor ](#zebra-tech-d-opto-dissolved-oxygen-sensor-) - - [Calculated Variables ](#calculated-variables-) - - [Creating the array, logger, publishers ](#creating-the-array-logger-publishers-) - - [The variable array ](#the-variable-array-) - - [Creating Variables within an Array ](#creating-variables-within-an-array-) - - [Creating Variables and Pasting UUIDs from MonitorMyWatershed ](#creating-variables-and-pasting-uuids-from-monitormywatershed-) - - [Creating Variables within an Array ](#creating-variables-within-an-array--1) - - [The Logger Object ](#the-logger-object-) - - [Data Publishers ](#data-publishers-) - - [Monitor My Watershed ](#monitor-my-watershed-) - - [DreamHost ](#dreamhost-) - - [ThingSpeak ](#thingspeak-) - - [Ubidots ](#ubidots-) - - [Extra Working Functions ](#extra-working-functions-) - - [Arduino Setup Function ](#arduino-setup-function-) - - [Starting the Function ](#starting-the-function-) - - [Wait for USB ](#wait-for-usb-) - - [Printing a Hello ](#printing-a-hello-) - - [Serial Interrupts ](#serial-interrupts-) - - [Serial Begin ](#serial-begin-) - - [SAMD Pin Peripherals ](#samd-pin-peripherals-) - - [Flash the LEDs ](#flash-the-leds-) - - [Begin the Logger ](#begin-the-logger-) - - [Setup the Sensors ](#setup-the-sensors-) - - [Custom Modem Setup ](#custom-modem-setup-) - - [ESP8266 Baud Rate ](#esp8266-baud-rate-) - - [Skywire Pin Inversions ](#skywire-pin-inversions-) - - [SimCom SIM7080G Network Mode ](#simcom-sim7080g-network-mode-) - - [XBee Cellular Carrier ](#xbee-cellular-carrier-) - - [SARA R4 Cellular Carrier ](#sara-r4-cellular-carrier-) - - [Sync the Real Time Clock ](#sync-the-real-time-clock-) - - [Setup File on the SD card ](#setup-file-on-the-sd-card-) - - [Sleep until the First Data Collection Time ](#sleep-until-the-first-data-collection-time-) - - [Setup Complete ](#setup-complete-) - - [Arduino Loop Function ](#arduino-loop-function-) - - [A Typical Loop ](#a-typical-loop-) - - [A Complex Loop ](#a-complex-loop-) -[//]: # ( End GitHub Only ) +- [Example showing all possible functionality](#example-showing-all-possible-functionality) +- [Walking Through the Code](#walking-through-the-code) + - [Defines and Includes](#defines-and-includes) + - [Defines for the Arduino IDE](#defines-for-the-arduino-ide) + - [Library Includes](#library-includes) + - [Logger Settings](#logger-settings) + - [Creating Extra Serial Ports](#creating-extra-serial-ports) + - [AVR Boards](#avr-boards) + - [AltSoftSerial](#altsoftserial) + - [NeoSWSerial](#neoswserial) + - [SoftwareSerial with External Interrupts](#softwareserial-with-external-interrupts) + - [Software I2C/Wire](#software-i2cwire) + - [SAMD Boards](#samd-boards) + - [Assigning Serial Port Functionality](#assigning-serial-port-functionality) + - [Logging Options](#logging-options) + - [Wifi/Cellular Modem Options](#wificellular-modem-options) + - [Digi XBee Cellular - Transparent Mode](#digi-xbee-cellular---transparent-mode) + - [Digi XBee3 LTE-M - Bypass Mode](#digi-xbee3-lte-m---bypass-mode) + - [Digi XBee 3G - Bypass Mode](#digi-xbee-3g---bypass-mode) + - [Digi XBee S6B Wifi](#digi-xbee-s6b-wifi) + - [Espressif ESP8266](#espressif-esp8266) + - [Quectel BG96](#quectel-bg96) + - [Sequans Monarch](#sequans-monarch) + - [SIMCom SIM800](#simcom-sim800) + - [SIMCom SIM7000](#simcom-sim7000) + - [SIMCom SIM7080G (EnviroDIY LTE Bee\])](#simcom-sim7080g-envirodiy-lte-bee) + - [Sodaq GPRSBee](#sodaq-gprsbee) + - [u-blox SARA R410M](#u-blox-sara-r410m) + - [u-blox SARA U201](#u-blox-sara-u201) + - [Modem Measured Variables](#modem-measured-variables) + - [Sensors and Measured Variables](#sensors-and-measured-variables) + - [The processor as a sensor](#the-processor-as-a-sensor) + - [Maxim DS3231 RTC as a sensor](#maxim-ds3231-rtc-as-a-sensor) + - [AOSong AM2315](#aosong-am2315) + - [AOSong DHT](#aosong-dht) + - [Apogee SQ-212 Quantum Light Sensor](#apogee-sq-212-quantum-light-sensor) + - [Atlas Scientific EZO Circuits](#atlas-scientific-ezo-circuits) + - [Atlas Scientific EZO-CO2 Embedded NDIR Carbon Dioxide Sensor](#atlas-scientific-ezo-co2-embedded-ndir-carbon-dioxide-sensor) + - [Atlas Scientific EZO-DO Dissolved Oxygen Sensor](#atlas-scientific-ezo-do-dissolved-oxygen-sensor) + - [Atlas Scientific EZO-ORP Oxidation/Reduction Potential Sensor](#atlas-scientific-ezo-orp-oxidationreduction-potential-sensor) + - [Atlas Scientific EZO-pH Sensor](#atlas-scientific-ezo-ph-sensor) + - [Atlas Scientific EZO-RTD Temperature Sensor](#atlas-scientific-ezo-rtd-temperature-sensor) + - [Atlas Scientific EZO-EC Conductivity Sensor](#atlas-scientific-ezo-ec-conductivity-sensor) + - [Bosch BME280 Environmental Sensor](#bosch-bme280-environmental-sensor) + - [Bosch BMP388 and BMP398 Pressure Sensors](#bosch-bmp388-and-bmp398-pressure-sensors) + - [Campbell ClariVUE SDI-12 Turbidity Sensor](#campbell-clarivue-sdi-12-turbidity-sensor) + - [Campbell OBS3+ Analog Turbidity Sensor](#campbell-obs3-analog-turbidity-sensor) + - [Campbell RainVUE SDI-12 Precipitation Sensor](#campbell-rainvue-sdi-12-precipitation-sensor) + - [Decagon CTD-10 Conductivity, Temperature, and Depth Sensor](#decagon-ctd-10-conductivity-temperature-and-depth-sensor) + - [Decagon ES2 Conductivity and Temperature Sensor](#decagon-es2-conductivity-and-temperature-sensor) + - [Everlight ALS-PT19 Ambient Light Sensor](#everlight-als-pt19-ambient-light-sensor) + - [External Voltage via TI ADS1x15](#external-voltage-via-ti-ads1x15) + - [Freescale Semiconductor MPL115A2 Miniature I2C Digital Barometer](#freescale-semiconductor-mpl115a2-miniature-i2c-digital-barometer) + - [GroPoint Profile GPLP-8 Eight-Segment Soil Moisture and Temperature Profiling Probe](#gropoint-profile-gplp-8-eight-segment-soil-moisture-and-temperature-profiling-probe) + - [In-Situ Aqua/Level TROLL Pressure, Temperature, and Depth Sensor](#in-situ-aqualevel-troll-pressure-temperature-and-depth-sensor) + - [In-Situ RDO PRO-X Rugged Dissolved Oxygen Probe](#in-situ-rdo-pro-x-rugged-dissolved-oxygen-probe) + - [Keller RS485/Modbus Water Level Sensors](#keller-rs485modbus-water-level-sensors) + - [Keller Acculevel High Accuracy Submersible Level Transmitter](#keller-acculevel-high-accuracy-submersible-level-transmitter) + - [Keller Nanolevel Level Transmitter](#keller-nanolevel-level-transmitter) + - [Maxbotix HRXL Ultrasonic Range Finder](#maxbotix-hrxl-ultrasonic-range-finder) + - [Maxim DS18 One Wire Temperature Sensor](#maxim-ds18-one-wire-temperature-sensor) + - [Measurement Specialties MS5803-14BA Pressure Sensor](#measurement-specialties-ms5803-14ba-pressure-sensor) + - [Meter SDI-12 Sensors](#meter-sdi-12-sensors) + - [Meter ECH2O Soil Moisture Sensor](#meter-ech2o-soil-moisture-sensor) + - [Meter Hydros 21 Conductivity, Temperature, and Depth Sensor](#meter-hydros-21-conductivity-temperature-and-depth-sensor) + - [Meter Teros 11 Soil Moisture Sensor](#meter-teros-11-soil-moisture-sensor) + - [PaleoTerra Redox Sensors](#paleoterra-redox-sensors) + - [Trinket-Based Tipping Bucket Rain Gauge](#trinket-based-tipping-bucket-rain-gauge) + - [Sensirion SHT4X Digital Humidity and Temperature Sensor](#sensirion-sht4x-digital-humidity-and-temperature-sensor) + - [Northern Widget Tally Event Counter](#northern-widget-tally-event-counter) + - [TI INA219 High Side Current Sensor](#ti-ina219-high-side-current-sensor) + - [Turner Cyclops-7F Submersible Fluorometer](#turner-cyclops-7f-submersible-fluorometer) + - [Analog Electrical Conductivity using the Processor's Analog Pins](#analog-electrical-conductivity-using-the-processors-analog-pins) + - [VEGA VEGA PULS 21](#vega-vega-puls-21) + - [Yosemitech RS485/Modbus Environmental Sensors](#yosemitech-rs485modbus-environmental-sensors) + - [Yosemitech Y504 Dissolved Oxygen Sensor](#yosemitech-y504-dissolved-oxygen-sensor) + - [Yosemitech Y510 Turbidity Sensor](#yosemitech-y510-turbidity-sensor) + - [Yosemitech Y511 Turbidity Sensor with Wiper](#yosemitech-y511-turbidity-sensor-with-wiper) + - [Yosemitech Y514 Chlorophyll Sensor](#yosemitech-y514-chlorophyll-sensor) + - [Yosemitech Y520 Conductivity Sensor](#yosemitech-y520-conductivity-sensor) + - [Yosemitech Y532 pH Sensor](#yosemitech-y532-ph-sensor) + - [Yosemitech Y533 Oxidation Reduction Potential (ORP) Sensor](#yosemitech-y533-oxidation-reduction-potential-orp-sensor) + - [Yosemitech Y551 Carbon Oxygen Demand (COD) Sensor with Wiper](#yosemitech-y551-carbon-oxygen-demand-cod-sensor-with-wiper) + - [Yosemitech Y560 Ammonium Sensor](#yosemitech-y560-ammonium-sensor) + - [Yosemitech Y700 Pressure Sensor](#yosemitech-y700-pressure-sensor) + - [Yosemitech Y4000 Multi-Parameter Sonde](#yosemitech-y4000-multi-parameter-sonde) + - [Zebra Tech D-Opto Dissolved Oxygen Sensor](#zebra-tech-d-opto-dissolved-oxygen-sensor) + - [Calculated Variables](#calculated-variables) + - [Creating the array, logger, publishers](#creating-the-array-logger-publishers) + - [The variable array](#the-variable-array) + - [Creating Variables within an Array](#creating-variables-within-an-array) + - [Creating Variables and Pasting UUIDs from MonitorMyWatershed](#creating-variables-and-pasting-uuids-from-monitormywatershed) + - [Creating Variables within an Array](#creating-variables-within-an-array-1) + - [The Logger Object](#the-logger-object) + - [Data Publishers](#data-publishers) + - [Monitor My Watershed](#monitor-my-watershed) + - [DreamHost](#dreamhost) + - [ThingSpeak](#thingspeak) + - [Ubidots](#ubidots) + - [Extra Working Functions](#extra-working-functions) + - [Arduino Setup Function](#arduino-setup-function) + - [Starting the Function](#starting-the-function) + - [Wait for USB](#wait-for-usb) + - [Printing a Hello](#printing-a-hello) + - [Serial Interrupts](#serial-interrupts) + - [Serial Begin](#serial-begin) + - [SAMD Pin Peripherals](#samd-pin-peripherals) + - [Flash the LEDs](#flash-the-leds) + - [Begin the Logger](#begin-the-logger) + - [Setup the Sensors](#setup-the-sensors) + - [Custom Modem Setup](#custom-modem-setup) + - [ESP8266 Baud Rate](#esp8266-baud-rate) + - [Skywire Pin Inversions](#skywire-pin-inversions) + - [SimCom SIM7080G Network Mode](#simcom-sim7080g-network-mode) + - [XBee Cellular Carrier](#xbee-cellular-carrier) + - [SARA R4 Cellular Carrier](#sara-r4-cellular-carrier) + - [Sync the Real Time Clock](#sync-the-real-time-clock) + - [Setup File on the SD card](#setup-file-on-the-sd-card) + - [Sleep until the First Data Collection Time](#sleep-until-the-first-data-collection-time) + - [Setup Complete](#setup-complete) + - [Arduino Loop Function](#arduino-loop-function) + - [A Typical Loop](#a-typical-loop) + - [A Complex Loop](#a-complex-loop) +[//]: # ( End GitHub Only ) ## Defines and Includes ### Defines for the Arduino IDE + The top few lines of the examples set defines of buffer sizes and yields needed for the Arduino IDE. That IDE read any defines within the top few lines and applies them as build flags for the processor. -This is _not_ standard behavior for C++ (which is what Arduino code really is) - this is a unique aspect of the Arduino IDE. +This is *not* standard behavior for C++ (which is what Arduino code really is) - this is a unique aspect of the Arduino IDE. [//]: # ( @menusnip{defines} ) @@ -171,6 +172,7 @@ build_flags = -DTINY_GSM_RX_BUFFER=64 -DTINY_GSM_YIELD_MS=2 ``` + ___ ### Library Includes @@ -194,15 +196,14 @@ Among these are any sensors using RS232, RS485, RS422. Generally each serial variant (or sometimes each sensor) needs a dedicated serial "port" - its own connection to the processor. Most processors have built in dedicated wires for serial communication - "Hardware" serial. See the page on [Arduino streams](@ref page_arduino_streams) for much more detail about serial connections with Arduino processors. -_______ +___ #### AVR Boards -Most Arduino AVR style boards have very few (ie, one, or none) dedicated serial ports _available_ after counting out the programming serial port. +Most Arduino AVR style boards have very few (ie, one, or none) dedicated serial ports *available* after counting out the programming serial port. So to connect anything else, we need to try to emulate the processor serial functionality with a software library. This example shows three possible libraries that can be used to emulate a serial port on an AVR board. - ##### AltSoftSerial [AltSoftSerial](https://github.com/PaulStoffregen/AltSoftSerial) by Paul Stoffregen is the most accurate software serial port for AVR boards. @@ -212,7 +213,6 @@ See the [processor compatibility](@ref page_processor_compatibility) page for mo [//]: # ( @menusnip{altsoftserial} ) - ##### NeoSWSerial [NeoSWSerial](https://github.com/SRGDamia1/NeoSWSerial) is the best software serial that can be used on any pin supporting interrupts. @@ -225,7 +225,6 @@ Not all AVR boards are supported by NeoSWSerial. When using NeoSWSerial we will also have to actually set the data receiving (Rx) pin modes for interrupt in the [setup function](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_setup_serial_interrupts). - ##### SoftwareSerial with External Interrupts The "standard" software serial library uses interrupts that conflict with several other libraries used within this program. @@ -241,7 +240,6 @@ If you only want to use the serial line for incoming or outgoing data, set the o When using SoftwareSerial with External Interrupts we will also have to actually set the data receiving (Rx) pin modes for interrupt in the [setup function](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_setup_serial_interrupts). - ##### Software I2C/Wire This creates a software I2C (wire) instance that can be shared between multiple sensors. @@ -249,11 +247,11 @@ Only Testato's [SoftwareWire](https://github.com/Testato/SoftwareWire) library i [//]: # ( @menusnip{softwarewire} ) ---- +___ #### SAMD Boards -The SAMD21 supports up to 6 _hardware_ serial ports, which is _awesome_. +The SAMD21 supports up to 6 *hardware* serial ports, which is *awesome*. But, the Arduino core doesn't make use of all of them, so we have to assign them ourselves. This section of code assigns SERCOM's 1 and 2 to act as Serial2 and Serial3 on pins 10/11 and 5/2 respectively. @@ -264,10 +262,9 @@ These pin selections are based on the Adafruit Feather M0. In addition to creating the extra SERCOM ports here, the pins must be set up as the proper pin peripherals after the serial ports are begun. This is shown in the [SAMD Pin Peripherals section](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_setup_pin_periph) of the setup function. +NOTE: The SAMD51 board has an amazing *8* available SERCOM's, but I do not have any exmple code for using them. -NOTE: The SAMD51 board has an amazing _8_ available SERCOM's, but I do not have any exmple code for using them. - ---- +___ ### Assigning Serial Port Functionality @@ -281,7 +278,7 @@ Depending on how you rank the importance of each component, you can adjust these [//]: # ( @menusnip{assign_ports_sw} ) ---- +___ ### Logging Options @@ -292,11 +289,10 @@ This includes setting the time zone (daylight savings time is **NOT** applied) a ___ - ## Wifi/Cellular Modem Options This modem section is very lengthy because it contains the code with the constructor for every possible supported modem module. -Do _NOT_ try to use more than one modem at a time - it will _NOT_ work. +Do *NOT* try to use more than one modem at a time - it will *NOT* work. To create any of the modems, we follow a similar pattern: @@ -313,12 +309,12 @@ All the modems also need some sort of network credentials for internet access. For WiFi modems, you need the network name and password (assuming WPA2). For cellular models, you will need the APN assigned to you by the carrier you bought your SIM card from. - ### Digi XBee Cellular - Transparent Mode -This is the code to use for _any_ of Digi's cellular XBee or XBee3 modules. +This is the code to use for *any* of Digi's cellular XBee or XBee3 modules. All of them can be implented as a DigiXBeeCellularTransparent object - a subclass of DigiXBee and loggerModem. To create a DigiXBeeCellularTransparent object we need to know + - the serial object name, - the MCU pin controlling modem power, - the MCU pin connected to the status pin, @@ -339,11 +335,11 @@ Depending on your cellular carrier, it is best to select the proper carrier prof Setting these helps the modem to connect to network faster. This is shows in the [XBee Cellular Carrier](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_setup_xbeec_carrier) chunk of the setup function. - ### Digi XBee3 LTE-M - Bypass Mode This code is for Digi's LTE-M XBee3 based on the u-blox SARA R410M - used in bypass mode. To create a DigiXBeeLTEBypass object we need to know + - the serial object name, - the MCU pin controlling modem power, - the MCU pin connected to the status pin, @@ -361,11 +357,11 @@ Depending on your cellular carrier, it is best to select the proper carrier prof Setting these helps the modem to connect to network faster. This is shows in the [SARA R4 Cellular Carrier](@ref setup_r4_carrrier) chunk of the setup function. - ### Digi XBee 3G - Bypass Mode This code is for Digi's 3G/2G XBee based on the u-blox SARA U201 - used in bypass mode. To create a DigiXBee3GBypass object we need to know + - the serial object name, - the MCU pin controlling modem power, - the MCU pin connected to the status pin, @@ -383,6 +379,7 @@ A helpful table detailing the pins to use with the EnviroDIY Mayfly is available This code is for the Digi's S6B wifi module. To create a DigiXBeeWifi object we need to know + - the serial object name, - the MCU pin controlling modem power, - the MCU pin connected to the status pin, @@ -397,11 +394,11 @@ A helpful table detailing the pins to use with the EnviroDIY Mayfly is available [//]: # ( @menusnip{digi_xbee_wifi} ) - ### Espressif ESP8266 This code is for the Espressif ESP8266 or ESP32 operating with "AT" firmware. To create a EspressifESP8266 object we need to know + - the serial object name, - the MCU pin controlling modem power, - the reset pin (MCU pin connected to the ESP's `RSTB/DIO16`), @@ -413,13 +410,13 @@ Pins that do not apply should be set as -1. [//]: # ( @menusnip{espressif_esp8266} ) Because the ESP8266's default baud rate is too fast for an 8MHz board like the Mayfly, to use it you need to drop the baud rate down for sucessful communication. -You can set the slower baud rate using some external method, or useing the code from the ESP8266 Baud Rate(https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_setup_esp) part of the setup function below. - +You can set the slower baud rate using some external method, or useing the code from the ESP8266 Baud Rate() part of the setup function below. ### Quectel BG96 This code is for the Dragino, Nimbelink or other boards based on the Quectel BG96. To create a QuectelBG96 object we need to know + - the serial object name, - the MCU pin controlling modem power, - the MCU pin connected to the `STATUS` pin, @@ -434,11 +431,11 @@ Pins that do not apply should be set as -1. If you are interfacing with a Nimbelink Skywire board via the Skywire development board, you also need to handle the fact that the development board reverses the levels of the status, wake, and reset pins. Code to invert the pin levels is in the [Skywire Pin Inversions](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_setup_skywire) part of the setup function below. - ### Sequans Monarch This code is for the Nimbelink LTE-M Verizon/Sequans or other boards based on the Sequans Monarch series SoC. To create a SequansMonarch object we need to know + - the serial object name, - the MCU pin controlling modem power, - the MCU pin connected to either the `GPIO3/STATUS_LED` or `POWER_MON` pin, @@ -454,14 +451,14 @@ If you are interfacing with a Nimbelink Skywire board via the Skywire developmen Code to invert the pin levels is in the [Skywire Pin Inversions](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8ino-example.html#enu_walk_setup_skywire) part of the setup function below. The default baud rate of the SVZM20 is much too fast for almost all Arduino boards. -_Before_ attampting to connect a SVZM20 to an Arduino you should connect it to your computer and use AT commands to decrease the baud rate. +*Before* attampting to connect a SVZM20 to an Arduino you should connect it to your computer and use AT commands to decrease the baud rate. The proper command to decrease the baud rate to 9600 (8N1) is: `AT+IPR=9600`. - ### SIMCom SIM800 This code is for a SIMCom SIM800 or SIM900 or one of their many variants, including the Adafruit Fona and the Sodaq 2GBee R4. To create a SIMComSIM800 object we need to know + - the serial object name, - the MCU pin controlling modem power, - the MCU pin connected to the `STATUS` pin, @@ -471,16 +468,16 @@ To create a SIMComSIM800 object we need to know Pins that do not apply should be set as -1. -_NOTE:_ This is NOT the correct form for a Sodaq 2GBee R6 or R7. +*NOTE:* This is NOT the correct form for a Sodaq 2GBee R6 or R7. See the section for a 2GBee R6. [//]: # ( @menusnip{sim_com_sim800} ) - ### SIMCom SIM7000 This code is for a SIMCom SIM7000 or one of its variants. To create a SIMComSIM7000 object we need to know + - the serial object name, - the MCU pin controlling modem power, - the MCU pin connected to the `STATUS` pin, @@ -492,12 +489,12 @@ Pins that do not apply should be set as -1. [//]: # ( @menusnip{sim_com_sim7000} ) - ### SIMCom SIM7080G (EnviroDIY LTE Bee]) This code is for a SIMCom SIM7080G or one of its variants, including the [EnviroDIY LTE Bee](https://www.envirodiy.org/product/envirodiy-lte-bee-pack-of-5/). To create a SIMComSIM7080 object we need to know + - the serial object name, - the MCU pin controlling modem power, - the MCU pin connected to the `STATUS` pin, @@ -509,13 +506,13 @@ A helpful table detailing the pins to use with the EnviroDIY LTE Bee and the Env [//]: # ( @menusnip{sim_com_sim7080} ) - ### Sodaq GPRSBee This code is for the Sodaq 2GBee R6 and R7 based on the SIMCom SIM800. To create a Sodaq2GBeeR6 object we need to know + - the serial object name, -- the MCU pin controlling modem power, (**NOTE:** On the GPRSBee R6 and R7 the pin labeled as ON/OFF in Sodaq's diagrams is tied to _both_ the SIM800 power supply and the (inverted) SIM800 `PWRKEY`. +- the MCU pin controlling modem power, (**NOTE:** On the GPRSBee R6 and R7 the pin labeled as ON/OFF in Sodaq's diagrams is tied to *both* the SIM800 power supply and the (inverted) SIM800 `PWRKEY`. You should enter this pin as the power pin.) - and the SIM card's cellular access point name (APN). @@ -530,6 +527,7 @@ A helpful table detailing the pins to use with the Sodaq GPRSBee and the EnviroD This code is for modules based on the 4G LTE-M u-blox SARA R410M including the Sodaq UBee. To create a SodaqUBeeR410M object we need to know + - the serial object name, - the MCU pin controlling modem power, - the MCU pin connected to the `V_INT` pin (for status), @@ -550,6 +548,7 @@ This is shows in the [SARA R4 Cellular Carrier](@ref setup_r4_carrrier) chunk of This code is for modules based on the 3G/2G u-blox SARA U201 including the Sodaq UBee or the Sodaq 3GBee. To create a SodaqUBeeU201 object we need to know + - the serial object name, - the MCU pin controlling modem power, - the MCU pin connected to the `V_INT` pin (for status), @@ -567,7 +566,7 @@ A helpful table detailing the pins to use with the Sodaq UBee U201 and the Envir After creating the modem object, we can create Variable objects for each of the variables the modem is capable of measuring (Modem_SignalPercent, Modem_BatteryState, Modem_BatteryPercent, Modem_BatteryVoltage, and Modem_Temp). When we create the modem-linked variable objects, the first argument of the constructor, the loggerModem to like the variables to is required. The second and third arguments (the UUID and the variable code) included here are optional. -Note that here we create the variables for anything measured by _any_ of the modems, but most modems are not capable of measuring all of the values. +Note that here we create the variables for anything measured by *any* of the modems, but most modems are not capable of measuring all of the values. Some modem-measured values may be meaningless depending on the board configuration - often the battery parameters returned by a cellular component have little meaning because the module is downstream of a voltage regulator. [//]: # ( @menusnip{modem_variables} ) @@ -595,7 +594,7 @@ ___ ### Maxim DS3231 RTC as a sensor In addition to the time, we can also use the required DS3231 real time clock to report the temperature of the circuit board. -This temperature is _not_ equivalent to an environmental temperature measurement and should only be used to as a diagnostic. +This temperature is *not* equivalent to an environmental temperature measurement and should only be used to as a diagnostic. As above, we create both the sensor and the variables measured by it. @see @ref sensor_ds3231 @@ -632,7 +631,7 @@ ___ Here is the code for the Apogee SQ-212 Quantum Light Sensor. The SQ-212 is not directly connected to the MCU, but rather to an TI ADS1115 that communicates with the MCU. -The Arduino pin controlling power on/off and the analog data channel _on the TI ADS1115_ are required for the sensor constructor. +The Arduino pin controlling power on/off and the analog data channel *on the TI ADS1115* are required for the sensor constructor. If your ADD converter is not at the standard address of 0x48, you can enter its actual address as the third argument. The number of readings to average from the sensor is optional, but can be supplied as the fourth argument for the constructor if desired. @@ -642,7 +641,6 @@ The number of readings to average from the sensor is optional, but can be suppli ___ - ### Atlas Scientific EZO Circuits The next several sections are for Atlas Scientific EZO circuts and sensors. @@ -653,6 +651,7 @@ In the most common setup, with hardware I2C, the only required argument for the If you do not isolate them from your main I2C bus and you turn off power to the circuits between measurements the I2C lines will be pulled down to ground causing the I2C bus (and thus your logger) to crash. The default I2C addresses for the circuits are: + - CO2: 0x69 (105) - DO: 0x61 (97) - EC (conductivity): 0x64 (100) @@ -664,7 +663,6 @@ To use multiple circuits of the same type, re-address them. @see @ref atlas_group - #### Atlas Scientific EZO-CO2 Embedded NDIR Carbon Dioxide Sensor @see @ref sensor_atlas_co2 @@ -673,7 +671,6 @@ To use multiple circuits of the same type, re-address them. ___ - #### Atlas Scientific EZO-DO Dissolved Oxygen Sensor @see @ref sensor_atlas_do @@ -682,7 +679,6 @@ ___ ___ - #### Atlas Scientific EZO-ORP Oxidation/Reduction Potential Sensor @see @ref sensor_atlas_orp @@ -691,7 +687,6 @@ ___ ___ - #### Atlas Scientific EZO-pH Sensor @see @ref sensor_atlas_ph @@ -700,7 +695,6 @@ ___ ___ - #### Atlas Scientific EZO-RTD Temperature Sensor @see @ref sensor_atlas_rtd @@ -709,7 +703,6 @@ ___ ___ - #### Atlas Scientific EZO-EC Conductivity Sensor @see @ref sensor_atlas_cond @@ -718,7 +711,6 @@ ___ ___ - ### Bosch BME280 Environmental Sensor Here is the code for the Bosch BME280 environmental sensor. @@ -731,7 +723,6 @@ Keep in mind that the possible I2C addresses of the BME280 match those of the MS ___ - ### Bosch BMP388 and BMP398 Pressure Sensors @see @ref sensor_bmp3xx @@ -740,7 +731,6 @@ ___ ___ - #### Campbell ClariVUE SDI-12 Turbidity Sensor @see @ref sensor_clarivue @@ -749,14 +739,13 @@ ___ ___ - ### Campbell OBS3+ Analog Turbidity Sensor This is the code for the Campbell OBS3+. -The Arduino pin controlling power on/off, analog data channel _on the TI ADS1115_, and calibration values _in Volts_ for Ax^2 + Bx + C are required for the sensor constructor. +The Arduino pin controlling power on/off, analog data channel *on the TI ADS1115*, and calibration values *in Volts* for Ax^2 + Bx + C are required for the sensor constructor. A custom variable code can be entered as a second argument in the variable constructors, and it is very strongly recommended that you use this otherwise it will be very difficult to determine which return is high and which is low range on the sensor. If your ADD converter is not at the standard address of 0x48, you can enter its actual address as the third argument. -Do NOT forget that if you want to give a number of measurements to average, that comes _after_ the i2c address in the constructor! +Do NOT forget that if you want to give a number of measurements to average, that comes *after* the i2c address in the constructor! Note that to access both the high and low range returns, two instances must be created, one at the low range return pin and one at the high pin. @@ -766,7 +755,6 @@ Note that to access both the high and low range returns, two instances must be c ___ - #### Campbell RainVUE SDI-12 Precipitation Sensor @see @ref sensor_rainvue @@ -775,7 +763,6 @@ ___ ___ - #### Decagon CTD-10 Conductivity, Temperature, and Depth Sensor @see @ref sensor_decagon_ctd @@ -784,7 +771,6 @@ ___ ___ - ### Decagon ES2 Conductivity and Temperature Sensor The SDI-12 address of the sensor, the Arduino pin controlling power on/off, and the Arduino pin sending and receiving data are required for the sensor constructor. @@ -797,7 +783,6 @@ The data pin must be a pin that supports pin-change interrupts. ___ - #### Everlight ALS-PT19 Ambient Light Sensor @see @ref sensor_alspt19 @@ -806,11 +791,9 @@ ___ ___ - - ### External Voltage via TI ADS1x15 -The Arduino pin controlling power on/off and the analog data channel _on the TI ADS1115_ are required for the sensor constructor. +The Arduino pin controlling power on/off and the analog data channel *on the TI ADS1115* are required for the sensor constructor. If using a voltage divider to increase the measurable voltage range, enter the gain multiplier as the third argument. If your ADD converter is not at the standard address of 0x48, you can enter its actual address as the fourth argument. The number of measurements to average, if more than one is desired, goes as the fifth argument. @@ -821,7 +804,6 @@ The number of measurements to average, if more than one is desired, goes as the ___ - ### Freescale Semiconductor MPL115A2 Miniature I2C Digital Barometer The only input needed for the sensor constructor is the Arduino pin controlling power on/off and optionally the number of readings to average. @@ -833,7 +815,6 @@ Because this sensor can have only one I2C address (0x60), it is only possible to ___ - ### GroPoint Profile GPLP-8 Eight-Segment Soil Moisture and Temperature Profiling Probe @see @ref sensor_gplp8 @@ -842,7 +823,6 @@ ___ ___ - #### In-Situ Aqua/Level TROLL Pressure, Temperature, and Depth Sensor @see @ref sensor_insitu_troll @@ -851,7 +831,6 @@ ___ ___ - #### In-Situ RDO PRO-X Rugged Dissolved Oxygen Probe @see @ref sensor_insitu_rdo @@ -860,7 +839,6 @@ ___ ___ - ### Keller RS485/Modbus Water Level Sensors The next two sections are for Keller RS485/Modbus water level sensors. @@ -868,20 +846,19 @@ The sensor class constructors for each are nearly identical, except for the clas The sensor constructors require as input: the sensor modbus address, a stream instance for data (ie, `Serial`), and one or two power pins. The Arduino pin controlling the receive and data enable on your RS485-to-TTL adapter and the number of readings to average are optional. (Use -1 for the second power pin and -1 for the enable pin if these don't apply and you want to average more than one reading.) Please see the section "[Notes on Arduino Streams and Software Serial](https://envirodiy.github.io/ModularSensors/page_arduino_streams.html)" for more information about what streams can be used along with this library. -In tests on these sensors, SoftwareSerial_ExtInts _did not work_ to communicate with these sensors, because it isn't stable enough. +In tests on these sensors, SoftwareSerial_ExtInts *did not work* to communicate with these sensors, because it isn't stable enough. AltSoftSerial and HardwareSerial work fine. The serial ports for this example are created in the @ref menu_walk_serial_ports section and then assigned to modbus functionality in the @ref menu_walk_assign_ports_sw section. Up to two power pins are provided so that the RS485 adapter, the sensor and/or an external power relay can be controlled separately. If the power to everything is controlled by the same pin, use -1 for the second power pin or omit the argument. -If they are controlled by different pins _and no other sensors are dependent on power from either pin_ then the order of the pins doesn't matter. -If the RS485 adapter, sensor, or relay are controlled by different pins _and any other sensors are controlled by the same pins_ you should put the shared pin first and the un-shared pin second. -Both pins _cannot_ be shared pins. +If they are controlled by different pins *and no other sensors are dependent on power from either pin* then the order of the pins doesn't matter. +If the RS485 adapter, sensor, or relay are controlled by different pins *and any other sensors are controlled by the same pins* you should put the shared pin first and the un-shared pin second. +Both pins *cannot* be shared pins. @see @ref keller_group - #### Keller Acculevel High Accuracy Submersible Level Transmitter @see @ref sensor_acculevel @@ -890,7 +867,6 @@ Both pins _cannot_ be shared pins. ___ - #### Keller Nanolevel Level Transmitter @see @ref sensor_nanolevel @@ -899,7 +875,6 @@ ___ ___ - ### Maxbotix HRXL Ultrasonic Range Finder The Arduino pin controlling power on/off, a stream instance for received data (ie, `Serial`), and the Arduino pin controlling the trigger are required for the sensor constructor. @@ -914,7 +889,6 @@ The serial ports for this example are created in the @ref menu_walk_serial_ports ___ - ### Maxim DS18 One Wire Temperature Sensor The OneWire hex address of the sensor, the Arduino pin controlling power on/off, and the Arduino pin sending and receiving data are required for the sensor constructor, though the address can be omitted if only one sensor is used. @@ -928,7 +902,6 @@ The sensor address is programmed at the factory and cannot be changed. ___ - ### Measurement Specialties MS5803-14BA Pressure Sensor The only input needed is the Arduino pin controlling power on/off; the i2cAddressHex and maximum pressure are optional as is the number of readings to average. @@ -940,7 +913,6 @@ Keep in mind that the possible I2C addresses of the MS5803 match those of the BM ___ - ### Meter SDI-12 Sensors The next few sections are for Meter SDI-12 sensors. @@ -948,7 +920,6 @@ The SDI-12 address of the sensor, the Arduino pin controlling power on/off, and Optionally, you can include a number of distinct readings to average. The data pin must be a pin that supports pin-change interrupts. - #### Meter ECH2O Soil Moisture Sensor @see @ref sensor_fivetm @@ -957,7 +928,6 @@ The data pin must be a pin that supports pin-change interrupts. ___ - #### Meter Hydros 21 Conductivity, Temperature, and Depth Sensor @see @ref sensor_hydros21 @@ -966,7 +936,6 @@ ___ ___ - #### Meter Teros 11 Soil Moisture Sensor @see @ref sensor_teros11 @@ -975,7 +944,6 @@ ___ ___ - ### PaleoTerra Redox Sensors Because older versions of these sensors all ship with the same I2C address, and more than one is frequently used at different soil depths in the same profile, this module has an optional dependence on Testato's [SoftwareWire](https://github.com/Testato/SoftwareWire) library for software I2C. @@ -987,7 +955,9 @@ The constructors for the software I2C implementation requires either the SCL and All variants of the constructor require the Arduino power pin. The I2C address can be given if it the sensor is not set to the default of 0x68. A number of readings to average can also be given. -**** + +___ + @warning Either all or none of your attached redox probes may use software I2C. Using some with software I2C and others with hardware I2C is not supported. @@ -997,7 +967,6 @@ Using some with software I2C and others with hardware I2C is not supported. ___ - ### Trinket-Based Tipping Bucket Rain Gauge This is for use with a simple external I2C tipping bucket counter based on the [Adafriut Trinket](https://www.adafruit.com/product/1501). @@ -1012,7 +981,6 @@ Note that you cannot input a number of measurements to average because averaging ___ - #### Sensirion SHT4X Digital Humidity and Temperature Sensor @see @ref sensor_sht4x @@ -1021,7 +989,6 @@ ___ ___ - ### Northern Widget Tally Event Counter This is for use with Northern Widget's Tally event counter @@ -1039,7 +1006,6 @@ The counter should be continuously powered. ___ - ### TI INA219 High Side Current Sensor This is the code for the TI INA219 high side current and voltage sensor. @@ -1053,7 +1019,6 @@ The number of measurements to average, if more than one is desired, goes as the ___ - ### Turner Cyclops-7F Submersible Fluorometer This is the code for the Turner Cyclops-7F submersible fluorometer. @@ -1069,8 +1034,6 @@ The Cyclops sensors are *NOT* pre-calibrated and must be calibrated prior to dep ___ - - ### Analog Electrical Conductivity using the Processor's Analog Pins This is the code for the measuring electrical conductivity using the processor's internal ADC and analog input pins. @@ -1086,7 +1049,6 @@ For best results, you should also connect the AREF pin of your processors ADC to ___ - #### VEGA VEGA PULS 21 @see @ref sensor_vega_puls21 @@ -1095,7 +1057,6 @@ ___ ___ - ### Yosemitech RS485/Modbus Environmental Sensors The next several sections are for Yosemitech brand sensors. @@ -1105,7 +1066,7 @@ The Arduino pin controlling the receive and data enable on your RS485-to-TTL ada (Use -1 for the second power pin and -1 for the enable pin if these don't apply and you want to average more than one reading.) For most of the sensors, Yosemitech strongly recommends averaging multiple (in most cases 10) readings for each measurement. Please see the section "[Notes on Arduino Streams and Software Serial](https://envirodiy.github.io/ModularSensors/page_arduino_streams.html)" for more information about what streams can be used along with this library. -In tests on these sensors, SoftwareSerial_ExtInts _did not work_ to communicate with these sensors, because it isn't stable enough. +In tests on these sensors, SoftwareSerial_ExtInts *did not work* to communicate with these sensors, because it isn't stable enough. AltSoftSerial and HardwareSerial work fine. NeoSWSerial is a bit hit or miss, but can be used in a pinch. @@ -1113,7 +1074,6 @@ The serial ports for this example are created in the @ref menu_walk_serial_ports @see @ref yosemitech_group - #### Yosemitech Y504 Dissolved Oxygen Sensor @see @ref sensor_y504 @@ -1122,7 +1082,6 @@ The serial ports for this example are created in the @ref menu_walk_serial_ports ___ - #### Yosemitech Y510 Turbidity Sensor @see @ref sensor_y510 @@ -1131,7 +1090,6 @@ ___ ___ - #### Yosemitech Y511 Turbidity Sensor with Wiper @see @ref sensor_y511 @@ -1140,7 +1098,6 @@ ___ ___ - #### Yosemitech Y514 Chlorophyll Sensor @see @ref sensor_y514 @@ -1149,7 +1106,6 @@ ___ ___ - #### Yosemitech Y520 Conductivity Sensor @see @ref sensor_y520 @@ -1158,7 +1114,6 @@ ___ ___ - #### Yosemitech Y532 pH Sensor @see @ref sensor_y532 @@ -1167,7 +1122,6 @@ ___ ___ - #### Yosemitech Y533 Oxidation Reduction Potential (ORP) Sensor @see @ref sensor_y533 @@ -1176,7 +1130,6 @@ ___ ___ - #### Yosemitech Y551 Carbon Oxygen Demand (COD) Sensor with Wiper @see @ref sensor_y551 @@ -1185,7 +1138,6 @@ ___ ___ - #### Yosemitech Y560 Ammonium Sensor @see @ref sensor_y551 @@ -1194,7 +1146,6 @@ ___ ___ - #### Yosemitech Y700 Pressure Sensor @see @ref sensor_y700 @@ -1203,7 +1154,6 @@ ___ ___ - #### Yosemitech Y4000 Multi-Parameter Sonde @see @ref sensor_y4000 @@ -1212,7 +1162,6 @@ ___ ___ - ### Zebra Tech D-Opto Dissolved Oxygen Sensor The SDI-12 address of the sensor, the Arduino pin controlling power on/off, and the Arduino pin sending and receiving data are required for the sensor constructor. @@ -1225,7 +1174,6 @@ The data pin must be a pin that supports pin-change interrupts. ___ - ## Calculated Variables Create new Variable objects calculated from the measured variables. @@ -1250,7 +1198,6 @@ Here we use the `new` keyword to create multiple variables and get pointers to t [//]: # ( @menusnip{variables_create_in_array} ) - #### Creating Variables and Pasting UUIDs from MonitorMyWatershed If you are sending data to monitor my watershed, it is much easier to create the variables in an array and then to paste the UUID's all together as copied from the "View Token UUID List" link for a site. @@ -1258,7 +1205,6 @@ If using this method, be very, very, very careful to make sure the order of your [//]: # ( @menusnip{variables_separate_uuids} ) - #### Creating Variables within an Array You can also create and name variable pointer objects outside of the array (as is demonstrated in all of the code chunks here) and then reference those pointers inside of the array like so: @@ -1267,7 +1213,6 @@ You can also create and name variable pointer objects outside of the array (as i ___ - ### The Logger Object Now that we've created the array, we can actually create the #Logger object. @@ -1282,7 +1227,7 @@ Here we set up all three possible data publisers and link all of them to the sam #### Monitor My Watershed -To publish data to the Monitor My Watershed / EnviroDIY Data Sharing Portal first you must register yourself as a user at https://monitormywatershed.org or https://data.envirodiy.org. +To publish data to the Monitor My Watershed / EnviroDIY Data Sharing Portal first you must register yourself as a user at or . Then you must register your site. After registering your site, a sampling feature and registration token for that site should be visible on the site page. @@ -1334,7 +1279,7 @@ In Arduino coding, the classic "main" function is replaced by two functions: set The setup() function runs once when the board boots or restarts. It usually contains many functions that set the mode of input and output pins and prints out some debugging information to the serial port. These functions are frequently named "begin". -Because we have a _lot_ of parts to set up, there's a lot going on in this function! +Because we have a *lot* of parts to set up, there's a lot going on in this function! Let's break it down. @@ -1370,11 +1315,13 @@ The [NeoSWSerial](https://envirodiy.github.io/ModularSensors/menu_a_la_carte_8in **NOTE:** If you create more than one NeoSWSerial or Software serial object, you need to call the enableInterrupt function for each Rx pin! For NeoSWSerial we use: + ```cpp enableInterrupt(neoSSerial1Rx, neoSSerial1ISR, CHANGE); ``` For SoftwareSerial with External interrupts we use: + ```cpp enableInterrupt(softSerialRx, SoftwareSerial_ExtInts::handle_interrupt, CHANGE); @@ -1507,16 +1454,18 @@ ___ This is the loop function which will run repeatedly as long as the board is turned on. **NOTE:** This example has code for both a typical simple loop and a complex loop that calls lower level logger functions. -You should only pick _one_ loop function and delete the other. +You should only pick *one* loop function and delete the other. ### A Typical Loop After the incredibly long setup function, we can do the vast majority of all logger work in a very simple loop function. Every time the logger wakes we check the battery voltage and do 1 of three things: + 1. If the battery is very low, go immediately back to sleep and hope the sun comes back out 2. If the battery is at a moderate level, attempt to collect data from sensors, but do not attempt to publish data. The modem the biggest power user of the whole system. 3. + At full power, do everything. [//]: # ( @menusnip{simple_loop} ) diff --git a/examples/simple_logging/ReadMe.md b/examples/simple_logging/ReadMe.md index 372e082a7..a5c8cbd16 100644 --- a/examples/simple_logging/ReadMe.md +++ b/examples/simple_logging/ReadMe.md @@ -13,31 +13,33 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [Simple Logging](#simple-logging) -- [Unique Features of the Simple Logging Example](#unique-features-of-the-simple-logging-example) -- [To Use this Example](#to-use-this-example) - - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) - - [Set the logger ID](#set-the-logger-id) - - [Upload!](#upload) + - [Unique Features of the Simple Logging Example](#unique-features-of-the-simple-logging-example) + - [To Use this Example](#to-use-this-example) + - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) + - [Set the logger ID](#set-the-logger-id) + - [Upload!](#upload) [//]: # ( End GitHub Only ) +## Unique Features of the Simple Logging Example - -# Unique Features of the Simple Logging Example - Only logs data to an SD card. -# To Use this Example +## To Use this Example + +### Prepare and set up PlatformIO -## Prepare and set up PlatformIO - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/simple_logging/platformio.ini) file in the examples/simple_logging folder on GitHub. - - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. - - Without this, the program won't compile. + - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. + - Without this, the program won't compile. - Open [simple_logging.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/simple_logging/simple_logging.ino) and save it to your computer. Put it into the src directory of your project. - - Delete main.cpp in that folder. + - Delete main.cpp in that folder. + +### Set the logger ID -## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -45,12 +47,12 @@ _______ const char *LoggerID = "XXXX"; ``` -## Upload! +### Upload! + - Test everything at home **before** deploying out in the wild! _______ - [//]: # ( @section example_simple_logging_pio_config PlatformIO Configuration ) [//]: # ( @include{lineno} simple_logging/platformio.ini ) diff --git a/examples/simple_logging_LearnEnviroDIY/ReadMe.md b/examples/simple_logging_LearnEnviroDIY/ReadMe.md index 2c78f3612..3b5635525 100644 --- a/examples/simple_logging_LearnEnviroDIY/ReadMe.md +++ b/examples/simple_logging_LearnEnviroDIY/ReadMe.md @@ -15,32 +15,36 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [Learn EnviroDIY Course](#learn-envirodiy-course) -- [Unique Features of the Learn EnviroDIY Example](#unique-features-of-the-learn-envirodiy-example) -- [To Use this Example](#to-use-this-example) - - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) - - [Set the logger ID](#set-the-logger-id) - - [Upload!](#upload) + - [Unique Features of the Learn EnviroDIY Example](#unique-features-of-the-learn-envirodiy-example) + - [To Use this Example](#to-use-this-example) + - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) + - [Set the logger ID](#set-the-logger-id) + - [Upload!](#upload) [//]: # ( End GitHub Only ) _______ -# Unique Features of the Learn EnviroDIY Example +## Unique Features of the Learn EnviroDIY Example + - Only logs data to an SD card. - Uses a few more sensors than the other simple logging example -# To Use this Example +## To Use this Example + +### Prepare and set up PlatformIO -## Prepare and set up PlatformIO - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/simple_logging_LearnEnviroDIY/platformio.ini) file in the examples/simple_logging_LearnEnviroDIY folder on GitHub. - - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. - - Without this, the program won't compile. + - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. + - Without this, the program won't compile. - Open [simple_logging_LearnEnviroDIY.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/simple_logging_LearnEnviroDIY/simple_logging_LearnEnviroDIY.ino) and save it to your computer. Put it into the src directory of your project. - - Delete main.cpp in that folder. + - Delete main.cpp in that folder. + +### Set the logger ID -## Set the logger ID - Change the "XXXX" in this section of code to the loggerID assigned by Stroud: ```cpp @@ -48,13 +52,12 @@ _______ const char *LoggerID = "XXXX"; ``` -## Upload! +### Upload! + - Test everything at home **before** deploying out in the wild! _______ - - [//]: # ( @section example_learn_envirodiy_pio_config PlatformIO Configuration ) [//]: # ( @include{lineno} simple_logging_LearnEnviroDIY/platformio.ini ) diff --git a/examples/single_sensor/ReadMe.md b/examples/single_sensor/ReadMe.md index e7fb2a3d5..858a2b775 100644 --- a/examples/single_sensor/ReadMe.md +++ b/examples/single_sensor/ReadMe.md @@ -10,36 +10,39 @@ _______ [//]: # ( @m_footernavigation ) [//]: # ( Start GitHub Only ) + - [Using a Single Sensor](#using-a-single-sensor) -- [Unique Features of the Single Sensor Example](#unique-features-of-the-single-sensor-example) -- [To Use this Example](#to-use-this-example) - - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) - - [Upload!](#upload) + - [Unique Features of the Single Sensor Example](#unique-features-of-the-single-sensor-example) + - [To Use this Example](#to-use-this-example) + - [Prepare and set up PlatformIO](#prepare-and-set-up-platformio) + - [Upload!](#upload) [//]: # ( End GitHub Only ) _______ -# Unique Features of the Single Sensor Example +## Unique Features of the Single Sensor Example + - Only communicates with and collects data from a single sensor. - Does not make use of any VariableArray or logging features. -# To Use this Example +## To Use this Example + +### Prepare and set up PlatformIO -## Prepare and set up PlatformIO - Create a new PlatformIO project - Replace the contents of the platformio.ini for your new project with the [platformio.ini](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/single_sensor/platformio.ini) file in the examples/single_sensor folder on GitHub. - - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. - - Without this, the program won't compile. + - It is important that your PlatformIO configuration has the lib_ldf_mode and build flags set as they are in the example. + - Without this, the program won't compile. - Open [single_sensor.ino](https://raw.githubusercontent.com/EnviroDIY/ModularSensors/master/examples/single_sensor/single_sensor.ino) and save it to your computer. Put it into the src directory of your project. - - Delete main.cpp in that folder. + - Delete main.cpp in that folder. + +### Upload! -## Upload! - Upload and see what happens _______ - [//]: # ( @section example_single_sensor_pio_config PlatformIO Configuration ) [//]: # ( @include{lineno} single_sensor/platformio.ini ) From 2a1af496159e1921343651b61d1484dd4fe4f16f Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 14 Jun 2024 12:58:52 -0400 Subject: [PATCH 081/138] Remove generated css Signed-off-by: Sara Damiano --- .../m-EnviroDIY+documentation.compiled.css | 4839 ----------------- 1 file changed, 4839 deletions(-) delete mode 100644 docs/css/m-EnviroDIY+documentation.compiled.css diff --git a/docs/css/m-EnviroDIY+documentation.compiled.css b/docs/css/m-EnviroDIY+documentation.compiled.css deleted file mode 100644 index 7b457fc2e..000000000 --- a/docs/css/m-EnviroDIY+documentation.compiled.css +++ /dev/null @@ -1,4839 +0,0 @@ -/* Generated using `./postprocess.py m-EnviroDIY.css m-documentation.css -o m-EnviroDIY+documentation.compiled.css`. Do not edit. */ - -/* - This file is part of m.css. - - Copyright © 2017, 2018, 2019, 2020, 2021, 2022, 2023 - Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -*, -::before, -::after { - box-sizing: border-box; -} -body { - margin: 0; -} -.m-container { - width: 100%; - margin: auto; - padding-left: 1rem; - padding-right: 1rem; -} -.m-row { - margin-left: -1rem; - margin-right: -1rem; -} -.m-row::after { - content: ' '; - clear: both; - display: table; -} -.m-row > [class*='m-col-'] { - position: relative; - padding: 1rem; -} -[class*='m-clearfix-']::after { - display: block; - content: ' '; - clear: both; -} -[class*='m-show-'] { - display: none; -} -.m-container-inflate, -:not(.m-row) > [class*='m-col-'] { - margin-bottom: 1rem; -} -.m-container-inflate:last-child, -:not(.m-row) > [class*='m-col-']:last-child { - margin-bottom: 0; -} -.m-container.m-nopad, -[class*='m-col-'].m-nopad, -.m-container.m-nopadx, -[class*='m-col-'].m-nopadx, -.m-container.m-nopadl, -[class*='m-col-'].m-nopadl { - padding-left: 0; -} -.m-container.m-nopad, -[class*='m-col-'].m-nopad, -.m-container.m-nopadx, -[class*='m-col-'].m-nopadx, -.m-container.m-nopadr, -[class*='m-col-'].m-nopadr { - padding-right: 0; -} -[class*='m-col-'].m-nopad, -[class*='m-col-'].m-nopady, -[class*='m-col-'].m-nopadt { - padding-top: 0; -} -[class*='m-col-'].m-nopad, -[class*='m-col-'].m-nopady, -[class*='m-col-'].m-nopadb, -.m-container-inflate.m-nopadb { - padding-bottom: 0; -} -[class*='m-col-t-'] { - float: left; -} -.m-left-t { - padding-right: 1rem; - float: left; -} -.m-right-t, -[class*='m-col-t-'].m-right-t { - padding-left: 1rem; - float: right; -} -.m-center-t, -[class*='m-col-t-'].m-center-t { - float: none; -} -.m-center-t, -[class*='m-col-t-'].m-center-t { - margin-left: auto; - margin-right: auto; - float: none; -} -.m-col-t-1 { - width: calc(1 * 100% / 12); -} -.m-col-t-2 { - width: calc(2 * 100% / 12); -} -.m-col-t-3 { - width: calc(3 * 100% / 12); -} -.m-col-t-4 { - width: calc(4 * 100% / 12); -} -.m-col-t-5 { - width: calc(5 * 100% / 12); -} -.m-col-t-6 { - width: calc(6 * 100% / 12); -} -.m-col-t-7 { - width: calc(7 * 100% / 12); -} -.m-col-t-8 { - width: calc(8 * 100% / 12); -} -.m-col-t-9 { - width: calc(9 * 100% / 12); -} -.m-col-t-10 { - width: calc(10 * 100% / 12); -} -.m-col-t-11 { - width: calc(11 * 100% / 12); -} -.m-col-t-12 { - width: calc(12 * 100% / 12); -} -.m-push-t-1 { - left: calc(1 * 100% / 12); -} -.m-push-t-2 { - left: calc(2 * 100% / 12); -} -.m-push-t-3 { - left: calc(3 * 100% / 12); -} -.m-push-t-4 { - left: calc(4 * 100% / 12); -} -.m-push-t-5 { - left: calc(5 * 100% / 12); -} -.m-push-t-6 { - left: calc(6 * 100% / 12); -} -.m-push-t-7 { - left: calc(7 * 100% / 12); -} -.m-push-t-8 { - left: calc(8 * 100% / 12); -} -.m-push-t-9 { - left: calc(9 * 100% / 12); -} -.m-push-t-10 { - left: calc(10 * 100% / 12); -} -.m-push-t-11 { - left: calc(11 * 100% / 12); -} -.m-pull-t-1 { - right: calc(1 * 100% / 12); -} -.m-pull-t-2 { - right: calc(2 * 100% / 12); -} -.m-pull-t-3 { - right: calc(3 * 100% / 12); -} -.m-pull-t-4 { - right: calc(4 * 100% / 12); -} -.m-pull-t-5 { - right: calc(5 * 100% / 12); -} -.m-pull-t-6 { - right: calc(6 * 100% / 12); -} -.m-pull-t-7 { - right: calc(7 * 100% / 12); -} -.m-pull-t-8 { - right: calc(8 * 100% / 12); -} -.m-pull-t-9 { - right: calc(9 * 100% / 12); -} -.m-pull-t-10 { - right: calc(10 * 100% / 12); -} -.m-pull-t-11 { - right: calc(11 * 100% / 12); -} -@media screen and (min-width: 576px) { - .m-container { - width: 560px; - } - .m-container-inflatable - .m-col-s-10 - .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { - margin-left: -10%; - margin-right: -10%; - } - .m-container-inflatable .m-col-s-10 .m-container-inflate.m-left-s { - margin-left: -10%; - } - .m-container-inflatable .m-col-s-10 .m-container-inflate.m-right-s { - margin-right: -10%; - } - [class*='m-col-s-'] { - float: left; - } - .m-left-s { - padding-right: 1rem; - float: left; - } - .m-right-s, - [class*='m-col-s-'].m-right-s { - padding-left: 1rem; - float: right; - } - .m-center-s, - [class*='m-col-s-'].m-center-s { - margin-left: auto; - margin-right: auto; - float: none; - } - .m-col-s-1 { - width: calc(1 * 100% / 12); - } - .m-col-s-2 { - width: calc(2 * 100% / 12); - } - .m-col-s-3 { - width: calc(3 * 100% / 12); - } - .m-col-s-4 { - width: calc(4 * 100% / 12); - } - .m-col-s-5 { - width: calc(5 * 100% / 12); - } - .m-col-s-6 { - width: calc(6 * 100% / 12); - } - .m-col-s-7 { - width: calc(7 * 100% / 12); - } - .m-col-s-8 { - width: calc(8 * 100% / 12); - } - .m-col-s-9 { - width: calc(9 * 100% / 12); - } - .m-col-s-10 { - width: calc(10 * 100% / 12); - } - .m-col-s-11 { - width: calc(11 * 100% / 12); - } - .m-col-s-12 { - width: calc(12 * 100% / 12); - } - .m-push-s-0 { - left: calc(0 * 100% / 12); - } - .m-push-s-1 { - left: calc(1 * 100% / 12); - } - .m-push-s-2 { - left: calc(2 * 100% / 12); - } - .m-push-s-3 { - left: calc(3 * 100% / 12); - } - .m-push-s-4 { - left: calc(4 * 100% / 12); - } - .m-push-s-5 { - left: calc(5 * 100% / 12); - } - .m-push-s-6 { - left: calc(6 * 100% / 12); - } - .m-push-s-7 { - left: calc(7 * 100% / 12); - } - .m-push-s-8 { - left: calc(8 * 100% / 12); - } - .m-push-s-9 { - left: calc(9 * 100% / 12); - } - .m-push-s-10 { - left: calc(10 * 100% / 12); - } - .m-push-s-11 { - left: calc(11 * 100% / 12); - } - .m-pull-s-0 { - right: calc(0 * 100% / 12); - } - .m-pull-s-1 { - right: calc(1 * 100% / 12); - } - .m-pull-s-2 { - right: calc(2 * 100% / 12); - } - .m-pull-s-3 { - right: calc(3 * 100% / 12); - } - .m-pull-s-4 { - right: calc(4 * 100% / 12); - } - .m-pull-s-5 { - right: calc(5 * 100% / 12); - } - .m-pull-s-6 { - right: calc(6 * 100% / 12); - } - .m-pull-s-7 { - right: calc(7 * 100% / 12); - } - .m-pull-s-8 { - right: calc(8 * 100% / 12); - } - .m-pull-s-9 { - right: calc(9 * 100% / 12); - } - .m-pull-s-10 { - right: calc(10 * 100% / 12); - } - .m-pull-s-11 { - right: calc(11 * 100% / 12); - } - .m-clearfix-t::after { - display: none; - } - .m-hide-s { - display: none; - } - .m-show-s { - display: block; - } - .m-col-s-none { - width: auto; - float: none; - } -} -@media screen and (min-width: 768px) { - .m-container { - width: 750px; - } - .m-container-inflatable - .m-col-m-10 - .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { - margin-left: -10%; - margin-right: -10%; - } - .m-container-inflatable .m-col-m-10 .m-container-inflate.m-left-m { - margin-left: -10%; - } - .m-container-inflatable .m-col-m-10 .m-container-inflate.m-right-m { - margin-right: -10%; - } - [class*='m-col-m-'] { - float: left; - } - .m-left-m { - padding-right: 1rem; - float: left; - } - .m-right-m, - [class*='m-col-m-'].m-right-m { - padding-left: 1rem; - float: right; - } - .m-center-m, - [class*='m-col-m-'].m-center-m { - margin-left: auto; - margin-right: auto; - float: none; - } - .m-col-m-1 { - width: calc(1 * 100% / 12); - } - .m-col-m-2 { - width: calc(2 * 100% / 12); - } - .m-col-m-3 { - width: calc(3 * 100% / 12); - } - .m-col-m-4 { - width: calc(4 * 100% / 12); - } - .m-col-m-5 { - width: calc(5 * 100% / 12); - } - .m-col-m-6 { - width: calc(6 * 100% / 12); - } - .m-col-m-7 { - width: calc(7 * 100% / 12); - } - .m-col-m-8 { - width: calc(8 * 100% / 12); - } - .m-col-m-9 { - width: calc(9 * 100% / 12); - } - .m-col-m-10 { - width: calc(10 * 100% / 12); - } - .m-col-m-11 { - width: calc(11 * 100% / 12); - } - .m-col-m-12 { - width: calc(12 * 100% / 12); - } - .m-push-m-0 { - left: calc(0 * 100% / 12); - } - .m-push-m-1 { - left: calc(1 * 100% / 12); - } - .m-push-m-2 { - left: calc(2 * 100% / 12); - } - .m-push-m-3 { - left: calc(3 * 100% / 12); - } - .m-push-m-4 { - left: calc(4 * 100% / 12); - } - .m-push-m-5 { - left: calc(5 * 100% / 12); - } - .m-push-m-6 { - left: calc(6 * 100% / 12); - } - .m-push-m-7 { - left: calc(7 * 100% / 12); - } - .m-push-m-8 { - left: calc(8 * 100% / 12); - } - .m-push-m-9 { - left: calc(9 * 100% / 12); - } - .m-push-m-10 { - left: calc(10 * 100% / 12); - } - .m-push-m-11 { - left: calc(11 * 100% / 12); - } - .m-pull-m-0 { - right: calc(0 * 100% / 12); - } - .m-pull-m-1 { - right: calc(1 * 100% / 12); - } - .m-pull-m-2 { - right: calc(2 * 100% / 12); - } - .m-pull-m-3 { - right: calc(3 * 100% / 12); - } - .m-pull-m-4 { - right: calc(4 * 100% / 12); - } - .m-pull-m-5 { - right: calc(5 * 100% / 12); - } - .m-pull-m-6 { - right: calc(6 * 100% / 12); - } - .m-pull-m-7 { - right: calc(7 * 100% / 12); - } - .m-pull-m-8 { - right: calc(8 * 100% / 12); - } - .m-pull-m-9 { - right: calc(9 * 100% / 12); - } - .m-pull-m-10 { - right: calc(10 * 100% / 12); - } - .m-pull-m-11 { - right: calc(11 * 100% / 12); - } - .m-clearfix-s::after { - display: none; - } - .m-hide-m { - display: none; - } - .m-show-m { - display: block; - } - .m-col-m-none { - width: auto; - float: none; - } -} -@media screen and (min-width: 992px) { - .m-container { - width: 960px; - } - .m-container-inflatable - .m-col-l-10 - .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { - margin-left: -10%; - margin-right: -10%; - } - .m-container-inflatable .m-col-l-10 .m-container-inflate.m-left-l { - margin-left: -10%; - } - .m-container-inflatable .m-col-l-10 .m-container-inflate.m-right-l { - margin-right: -10%; - } - [class*='m-col-l-'] { - float: left; - } - .m-left-l { - padding-right: 1rem; - float: left; - } - .m-right-l, - [class*='m-col-l-'].m-right-l { - padding-left: 1rem; - float: right; - } - .m-center-l, - [class*='m-col-l-'].m-center-l { - margin-left: auto; - margin-right: auto; - float: none; - } - .m-col-l-1 { - width: calc(1 * 100% / 12); - } - .m-col-l-2 { - width: calc(2 * 100% / 12); - } - .m-col-l-3 { - width: calc(3 * 100% / 12); - } - .m-col-l-4 { - width: calc(4 * 100% / 12); - } - .m-col-l-5 { - width: calc(5 * 100% / 12); - } - .m-col-l-6 { - width: calc(6 * 100% / 12); - } - .m-col-l-7 { - width: calc(7 * 100% / 12); - } - .m-col-l-8 { - width: calc(8 * 100% / 12); - } - .m-col-l-9 { - width: calc(9 * 100% / 12); - } - .m-col-l-10 { - width: calc(10 * 100% / 12); - } - .m-col-l-11 { - width: calc(11 * 100% / 12); - } - .m-col-l-12 { - width: calc(12 * 100% / 12); - } - .m-push-l-0 { - left: calc(0 * 100% / 12); - } - .m-push-l-1 { - left: calc(1 * 100% / 12); - } - .m-push-l-2 { - left: calc(2 * 100% / 12); - } - .m-push-l-3 { - left: calc(3 * 100% / 12); - } - .m-push-l-4 { - left: calc(4 * 100% / 12); - } - .m-push-l-5 { - left: calc(5 * 100% / 12); - } - .m-push-l-6 { - left: calc(6 * 100% / 12); - } - .m-push-l-7 { - left: calc(7 * 100% / 12); - } - .m-push-l-8 { - left: calc(8 * 100% / 12); - } - .m-push-l-9 { - left: calc(9 * 100% / 12); - } - .m-push-l-10 { - left: calc(10 * 100% / 12); - } - .m-push-l-11 { - left: calc(11 * 100% / 12); - } - .m-pull-l-0 { - right: calc(0 * 100% / 12); - } - .m-pull-l-1 { - right: calc(1 * 100% / 12); - } - .m-pull-l-2 { - right: calc(2 * 100% / 12); - } - .m-pull-l-3 { - right: calc(3 * 100% / 12); - } - .m-pull-l-4 { - right: calc(4 * 100% / 12); - } - .m-pull-l-5 { - right: calc(5 * 100% / 12); - } - .m-pull-l-6 { - right: calc(6 * 100% / 12); - } - .m-pull-l-7 { - right: calc(7 * 100% / 12); - } - .m-pull-l-8 { - right: calc(8 * 100% / 12); - } - .m-pull-l-9 { - right: calc(9 * 100% / 12); - } - .m-pull-l-10 { - right: calc(10 * 100% / 12); - } - .m-pull-l-11 { - right: calc(11 * 100% / 12); - } - .m-clearfix-m::after { - display: none; - } - .m-hide-l { - display: none; - } - .m-show-l { - display: block; - } - .m-col-l-none { - width: auto; - float: none; - } -} - -html { - font-size: 14px; - background-color: #e8e8e8; -} -body { - font-family: 'Roboto', sans-serif; - font-size: 14px; - line-height: normal; - color: #000000; -} -h1, -h2, -h3, -h4, -h5, -h6 { - margin-top: 0; - font-weight: 300; -} -h1 { - margin-bottom: 1rem; -} -h2, -h3, -h4, -h5, -h6 { - margin-bottom: 0.5rem; -} -p, -ul, -ol, -dl { - margin-top: 0; -} -ul, -ol { - padding-left: 2rem; -} -ul ol, -ul ul, -ol ol, -ol ul { - margin-bottom: 0; -} -main p { - text-indent: 1.5rem; - text-align: justify; -} -main p.m-noindent, -li > p, -dd > p, -table.m-table td > p { - text-indent: 0; - text-align: left; -} -blockquote { - margin-top: 0; - margin-left: 1rem; - margin-right: 1rem; - padding: 1rem; - border-left-style: solid; - border-left-width: 0.25rem; -} -hr { - width: 75%; - border-width: 0.0625rem; - border-style: solid; -} -blockquote, -hr { - border-color: #92d050; -} -strong, -.m-text.m-strong { - font-weight: bold; -} -em, -.m-text.m-em { - font-style: italic; -} -s, -.m-text.m-s { - text-decoration: line-through; -} -sub, -sup, -.m-text.m-sub, -.m-text.m-sup { - font-size: 0.75rem; - line-height: 0; - position: relative; - vertical-align: baseline; -} -sup, -.m-text.m-sup { - top: -0.35rem; -} -sub, -.m-text.m-sub { - bottom: -0.2rem; -} -abbr { - cursor: help; - text-decoration: underline dotted; -} -a { - color: #26a9e0; -} -a.m-flat { - text-decoration: none; -} -a:hover, -a:focus, -a:active { - color: #26a9e0; -} -a img { - border: 0; -} -svg a { - cursor: pointer; -} -mark { - padding: 0.0625rem; - background-color: #e6e69c; - color: #4c93d3; -} -.m-link-wrap { - word-break: break-all; -} -pre, -code { - font-family: 'Monaco', monospace, monospace, monospace; - font-size: 0.95em; - color: #000000; - background-color: #f7f7f7; -} -pre.m-console, -code.m-console { - color: #000000; - background-color: #f7f7f7; -} -pre { - padding: 0.5rem 1rem; - border-radius: 0px; - overflow-x: auto; - margin-top: 0; -} -pre.m-console-wrap { - white-space: pre-wrap; - word-break: break-all; -} -code { - padding: 0.125rem; -} -*:focus { - outline-color: #ffffff; -} -div.m-scroll { - max-width: 100%; - overflow-x: auto; -} -.m-fullwidth { - width: 100%; -} -.m-spacing-150 { - line-height: 1.5rem; -} -.m-text-center, -.m-text-center.m-noindent, -table.m-table th.m-text-center, -.m-text-center p { - text-align: center; -} -.m-text-left, -.m-text-left.m-noindent, -table.m-table th.m-text-left, -.m-text-right p { - text-align: left; -} -.m-text-right, -.m-text-right.m-noindent, -table.m-table th.m-text-right, -.m-text-right p { - text-align: right; -} -.m-text-top, -table.m-table th.m-text-top, -table.m-table td.m-text-top { - vertical-align: top; -} -.m-text-middle, -table.m-table th.m-text-middle, -table.m-table td.m-text-middle { - vertical-align: middle; -} -.m-text-bottom, -table.m-table th.m-text-bottom, -table.m-table td.m-text-bottom { - vertical-align: bottom; -} -.m-text.m-tiny { - font-size: 50%; -} -.m-text.m-small { - font-size: 85.4%; -} -.m-text.m-big { - font-size: 117%; -} -h1 .m-thin, -h2 .m-thin, -h3 .m-thin, -h4 .m-thin, -h5 .m-thin, -h6 .m-thin { - font-weight: normal; - font-size: 75%; - color: #666; -} -ul.m-unstyled, -ol.m-unstyled { - list-style-type: none; - padding-left: 0; -} -ul[class*='m-block-'], -ol[class*='m-block-'] { - padding-left: 0; -} -ul[class*='m-block-'] li, -ol[class*='m-block-'] li { - display: inline; -} -ul[class*='m-block-bar-'] li:not(:last-child)::after, -ol[class*='m-block-bar-'] li:not(:last-child)::after { - content: ' | '; -} -ul[class*='m-block-dot-'] li:not(:last-child)::after, -ol[class*='m-block-dot-'] li:not(:last-child)::after { - content: ' • '; -} -@media screen and (min-width: 576px) { - ul.m-block-bar-s, - ol.m-block-bar-s, - ul.m-block-dot-s, - ol.m-block-dot-s { - padding-left: 2rem; - } - ul.m-block-bar-s li, - ol.m-block-bar-s li, - ul.m-block-dot-s li, - ol.m-block-dot-s li { - display: list-item; - } - ul.m-block-bar-s li:not(:last-child)::after, - ol.m-block-bar-s li:not(:last-child)::after, - ul.m-block-dot-s li:not(:last-child)::after, - ol.m-block-dot-s li:not(:last-child)::after { - content: ''; - } -} -@media screen and (min-width: 768px) { - ul.m-block-bar-m, - ol.m-block-bar-m, - ul.m-block-dot-m, - ol.m-block-dot-m { - padding-left: 2rem; - } - ul.m-block-bar-m li, - ol.m-block-bar-m li, - ul.m-block-dot-m li, - ol.m-block-dot-m li { - display: list-item; - } - ul.m-block-bar-m li:not(:last-child)::after, - ol.m-block-bar-m li:not(:last-child)::after, - ul.m-block-dot-m li:not(:last-child)::after, - ol.m-block-dot-m li:not(:last-child)::after { - content: ''; - } -} -@media screen and (min-width: 992px) { - ul.m-block-bar-l, - ol.m-block-bar-l, - ul.m-block-dot-l, - ol.m-block-dot-l { - padding-left: 2rem; - } - ul.m-block-bar-l li, - ol.m-block-bar-l li, - ul.m-block-dot-l li, - ol.m-block-dot-l li { - display: list-item; - } - ul.m-block-bar-l li:not(:last-child)::after, - ol.m-block-bar-l li:not(:last-child)::after, - ul.m-block-dot-l li:not(:last-child)::after, - ol.m-block-dot-l li:not(:last-child)::after { - content: ''; - } -} -p.m-poem { - text-indent: 0; - text-align: left; - margin-left: 1.5rem; -} -p.m-transition { - color: #ddd; - text-indent: 0; - text-align: center; - font-size: 2rem; -} -dl.m-diary { - margin-bottom: 1.25rem; -} -dl.m-diary:last-child { - margin-bottom: 0.25rem; -} -dl.m-diary dt { - font-weight: bold; - width: 6rem; - float: left; - clear: both; - padding-top: 0.25rem; -} -dl.m-diary dd { - padding-top: 0.25rem; - padding-left: 6rem; - margin-left: 0; -} -a.m-footnote, -dl.m-footnote dd span.m-footnote { - top: -0.35rem; - font-size: 0.75rem; - line-height: 0; - position: relative; - vertical-align: baseline; -} -a.m-footnote, -dl.m-footnote dd span.m-footnote a { - text-decoration: none; -} -a.m-footnote::before { - content: '['; -} -a.m-footnote::after { - content: ']'; -} -dl.m-footnote dt { - width: 1.5rem; - float: left; - clear: both; -} -dl.m-footnote dd { - margin-left: 1.5rem; -} -dl.m-footnote { - font-size: 85.4%; -} -dl.m-footnote dd span.m-footnote a { - font-weight: bold; - font-style: italic; -} -.m-container-inflatable { - background-color: #ffffff; -} -.m-note { - border-radius: 0px; - padding: 1rem; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-frame { - background-color: #e8e8e8; - border-style: solid; - border-width: 0.125rem; - border-radius: 0px; - border-color: #ddd; - padding: 0.875rem; -} -.m-block { - border-style: solid; - border-width: 0.0625rem; - border-radius: 0px; - border-color: #ddd; - padding: 0.9375rem 0.9375rem 0.9375rem 0.75rem; -} -.m-block.hr { - width: 75%; - border-width: 0.0625rem; - border-style: solid; - border-color: #92d050; -} -.m-block.m-row.hr { - width: 75%; - border-width: 0.0625rem; - border-style: solid; - border-color: #92d050; -} -.m-block.m-badge::after { - content: ' '; - display: block; - clear: both; -} -.m-block.m-badge h3 { - margin-left: 5rem; -} -.m-block.m-badge p { - margin-left: 5rem; - text-indent: 0; -} -.m-block.m-badge img { - width: 4rem; - height: 4rem; - border-radius: 0.5rem; - float: left; -} -div.m-button { - text-align: center; -} -div.m-button a { - display: inline-block; - border-radius: 0.5rem; - padding-top: 0.75rem; - padding-bottom: 0.75rem; - padding-left: 1.5rem; - padding-right: 1.5rem; - text-decoration: none; - font-size: 1.17rem; -} -div.m-button.m-fullwidth a { - display: block; - padding-left: 0.5rem; - padding-right: 0.5rem; -} -div.m-button a .m-big:first-child { - font-size: 1.37rem; - font-weight: bold; -} -div.m-button a .m-small:last-child { - font-size: 0.854rem; -} -.m-label { - border-radius: 0.5rem; - font-size: 75%; - font-weight: normal; - padding: 0.125rem 0.25rem; - vertical-align: 7.5%; -} -.m-label.m-flat { - border-width: 0.0625rem; - border-style: solid; - border-color: #666; - padding: 0.0625rem 0.1875rem; -} -table.m-table { - border-collapse: collapse; - margin-left: auto; - margin-right: auto; - font-size: 0.9em; -} -table.m-table.m-big { - margin-top: 1.75rem; -} -div.m-scroll > table.m-table:last-child { - margin-bottom: 0.0625rem; -} -table.m-table:not(.m-flat) tbody tr:hover { - background-color: #ddd; -} -table.m-table tr, -table.m-table th, -table.m-table td { - vertical-align: top; - border-style: solid; - border-top-width: 0.0625rem; - border-left-width: 0; - border-right-width: 0; - border-bottom-width: 0; - border-color: #ddd; -} -table.m-table tr:first-child th, -table.m-table tr:first-child td { - vertical-align: top; - border-style: solid; - border-top-width: 0.0625rem; - border-left-width: 0; - border-right-width: 0; - border-bottom-width: 0; - border-color: #ddd; -} -table.m-table tr:last-child th, -table.m-table tr:last-child td { - vertical-align: top; - border-style: solid; - border-top-width: 0.0625rem; - border-bottom-width: 0.0625rem; - border-left-width: 0; - border-right-width: 0; - border-color: #ddd; -} -table.m-table caption { - padding-bottom: 0.5rem; -} -table.m-table thead tr:first-child th, -table.m-table thead tr:first-child td { - border-top-width: 0.125rem; - border-left-width: 0; - border-right-width: 0; -} -table.m-table thead th, -table.m-table thead td { - border-bottom-width: 0.125rem; - vertical-align: bottom; - border-left-width: 0; - border-right-width: 0; -} -table.m-table tfoot th, -table.m-table tfoot td { - border-top-width: 0.125rem; -} -table.m-table th, -table.m-table td { - padding: 0.5rem; -} -table.m-table.m-big th, -table.m-table.m-big td { - padding: 0.75rem 1rem; -} -table.m-table th { - text-align: left; -} -table.m-table th.m-thin { - font-weight: normal; -} -table.m-table td.m-default, -table.m-table th.m-default, -table.m-table td.m-primary, -table.m-table th.m-primary, -table.m-table td.m-success, -table.m-table th.m-success, -table.m-table td.m-warning, -table.m-table th.m-warning, -table.m-table td.m-danger, -table.m-table th.m-danger, -table.m-table td.m-info, -table.m-table th.m-info, -table.m-table td.m-dim, -table.m-table th.m-dim, -table.m-table td.m-param, -table.m-table th.m-param, -table.m-table td.m-type, -table.m-table th.m-type { - padding-left: 0.4375rem; - padding-right: 0.4375rem; -} -table.m-table.m-big td.m-default, -table.m-table.m-big th.m-default, -table.m-table.m-big td.m-primary, -table.m-table.m-big th.m-primary, -table.m-table.m-big td.m-success, -table.m-table.m-big th.m-success, -table.m-table.m-big td.m-warning, -table.m-table.m-big th.m-warning, -table.m-table.m-big td.m-danger, -table.m-table.m-big th.m-danger, -table.m-table.m-big td.m-info, -table.m-table.m-big th.m-info, -table.m-table.m-big td.m-dim, -table.m-table.m-big th.m-dim, -table.m-table.m-big td.m-param, -table.m-table.m-big th.m-param, -table.m-table.m-big td.m-type, -table.m-table.m-big th.m-type { - padding-left: 0.9375rem; - padding-right: 0.9375rem; -} -table.m-table tr.m-default td, -table.m-table td.m-default, -table.m-table tr.m-default th, -table.m-table th.m-default, -table.m-table tr.m-primary td, -table.m-table td.m-primary, -table.m-table tr.m-primary th, -table.m-table th.m-primary, -table.m-table tr.m-success td, -table.m-table td.m-success, -table.m-table tr.m-success th, -table.m-table th.m-success, -table.m-table tr.m-warning td, -table.m-table td.m-warning, -table.m-table tr.m-warning th, -table.m-table th.m-warning, -table.m-table tr.m-danger td, -table.m-table td.m-danger, -table.m-table tr.m-danger th, -table.m-table th.m-danger, -table.m-table tr.m-info td, -table.m-table td.m-info, -table.m-table tr.m-info th, -table.m-table th.m-info, -table.m-table tr.m-dim td, -table.m-table td.m-dim, -table.m-table tr.m-dim th, -table.m-table th.m-dim, -table.m-table tr.m-param td, -table.m-table td.m-param, -table.m-table tr.m-param th, -table.m-table th.m-param, -table.m-table tr.m-type td, -table.m-table td.m-type, -table.m-table tr.m-type th, -table.m-table th.m-type { - border-color: #e8e8e8; -} -.m-note pre, -.m-note code, -table.m-table tr.m-default pre, -table.m-table tr.m-default code, -table.m-table td.m-default pre, -table.m-table td.m-default code, -table.m-table th.m-default pre, -table.m-table th.m-default code, -table.m-table tr.m-primary pre, -table.m-table tr.m-primary code, -table.m-table td.m-primary pre, -table.m-table td.m-primary code, -table.m-table th.m-primary pre, -table.m-table th.m-primary code, -table.m-table tr.m-success pre, -table.m-table tr.m-success code, -table.m-table td.m-success pre, -table.m-table td.m-success code, -table.m-table th.m-success pre, -table.m-table th.m-success code, -table.m-table tr.m-warning pre, -table.m-table tr.m-warning code, -table.m-table td.m-warning pre, -table.m-table td.m-warning code, -table.m-table th.m-warning pre, -table.m-table th.m-warning code, -table.m-table tr.m-danger pre, -table.m-table tr.m-danger code, -table.m-table td.m-danger pre, -table.m-table td.m-danger code, -table.m-table th.m-danger pre, -table.m-table th.m-danger code, -table.m-table tr.m-info pre, -table.m-table tr.m-info code, -table.m-table td.m-info pre, -table.m-table td.m-info code, -table.m-table th.m-info pre, -table.m-table th.m-info code, -table.m-table tr.m-dim pre, -table.m-table tr.m-dim code, -table.m-table td.m-dim pre, -table.m-table td.m-dim code, -table.m-table th.m-dim pre, -table.m-table th.m-dim code, -table.m-table tr.m-param pre, -table.m-table tr.m-param code, -table.m-table td.m-param pre, -table.m-table td.m-param code, -table.m-table th.m-param pre, -table.m-table th.m-param code, -table.m-table tr.m-type pre, -table.m-table tr.m-type code, -table.m-table td.m-type pre, -table.m-table td.m-type code, -table.m-table th.m-type pre, -table.m-table th.m-type code { - background-color: rgba(251, 240, 236, 0.5); -} -img.m-image, -svg.m-image, -video.m-image { - display: block; - margin-left: auto; - margin-right: auto; -} -div.m-image { - text-align: center; -} -img.m-image, -svg.m-image, -video.m-image, -div.m-image img, -div.m-image svg, -div.m-image video { - max-width: 100%; - border-radius: 0px; -} -div.m-image.m-fullwidth img, -div.m-image.m-fullwidth svg, -div.m-image.m-fullwidth video { - width: 100%; -} -img.m-image.m-badge, -div.m-image.m-badge img { - border-radius: 50%; -} -figure.m-figure { - max-width: 100%; - margin-top: 0; - margin-left: auto; - margin-right: auto; - position: relative; - display: table; -} -figure.m-figure::before { - position: absolute; - content: ' '; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: -1; - border-style: solid; - border-width: 0.125rem; - border-radius: 0px; - border-color: #ddd; -} -figure.m-figure.m-flat::before { - border-color: transparent; -} -figure.m-figure > * { - margin-left: 1rem; - margin-right: 1rem; - display: table-caption; - caption-side: bottom; -} -figure.m-figure > *:first-child { - display: inline; -} -figure.m-figure > *:last-child { - margin-bottom: 1rem !important; -} -figure.m-figure img, -figure.m-figure svg, -figure.m-figure video { - position: relative; - margin-left: 0; - margin-right: 0; - margin-bottom: 0; - border-top-left-radius: 0px; - border-top-right-radius: 0px; - max-width: 100%; -} -figure.m-figure.m-flat img, -figure.m-figure.m-flat svg, -figure.m-figure.m-flat video { - border-bottom-left-radius: 0px; - border-bottom-right-radius: 0px; -} -figure.m-figure a img, -figure.m-figure a svg, -figure.m-figure a video { - margin-left: -1rem; - margin-right: -1rem; -} -figure.m-figure.m-fullwidth, -figure.m-figure.m-fullwidth > * { - display: block; -} -figure.m-figure.m-fullwidth > *:first-child { - display: inline; -} -figure.m-figure.m-fullwidth img, -figure.m-figure.m-fullwidth svg, -figure.m-figure.m-fullwidth video { - width: 100%; -} -figure.m-figure.m-fullwidth::after { - content: ' '; - display: block; - margin-top: 1rem; - height: 1px; -} -.m-code-figure, -.m-console-figure { - margin-top: 0; - margin-left: 0; - margin-right: 0; - position: relative; - padding: 1rem; -} -.m-code-figure::before, -.m-console-figure::before { - position: absolute; - content: ' '; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: -1; - border-style: solid; - border-width: 0.125rem; - border-radius: 0px; -} -.m-code-figure::before { - border-color: #f7f7f7; -} -.m-console-figure::before { - border-color: #f7f7f7; -} -.m-code-figure.m-flat::before, -.m-console-figure.m-flat::before { - border-color: transparent; -} -.m-code-figure > pre:first-child, -.m-console-figure > pre:first-child { - position: relative; - margin: -1rem -1rem 1rem -1rem; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} -.m-code-figure > pre.m-nopad, -.m-console-figure > pre.m-nopad { - margin-left: -0.875rem; - margin-right: -0.875rem; - margin-top: -1rem; - margin-bottom: -0.875rem; - padding-left: 0.875rem; -} -figure.m-figure figcaption, -.m-code-figure figcaption, -.m-console-figure figcaption { - margin-top: 0.5rem; - margin-bottom: 0.5rem; - font-weight: 300; - font-size: 1.17rem; -} -figure.m-figure figcaption a, -.m-code-figure figcaption a, -.m-console-figure figcaption a { - text-decoration: none; -} -figure.m-figure figcaption .m-figure-description { - margin-top: 0.5rem; - font-weight: normal; - font-size: 1rem; -} -figure.m-figure figcaption .m-figure-description a { - text-decoration: underline; -} -.m-imagegrid > div { - background-color: #e8e8e8; -} -.m-imagegrid > div > figure { - display: block; - float: left; - position: relative; - margin: 0; -} -.m-imagegrid > div > figure > div, -.m-imagegrid > div > figure > figcaption, -.m-imagegrid > div > figure > a > div, -.m-imagegrid > div > figure > a > figcaption { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - border-color: #e8e8e8; - border-style: solid; - border-width: 0.25rem; - padding: 0.5rem; -} -.m-imagegrid > div > figure:first-child > div, -.m-imagegrid > div > figure:first-child > figcaption, -.m-imagegrid > div > figure:first-child > a > div, -.m-imagegrid > div > figure:first-child > a > figcaption { - border-left-width: 0; -} -.m-imagegrid > div > figure:last-child > div, -.m-imagegrid > div > figure:last-child > figcaption, -.m-imagegrid > div > figure:last-child > a > div, -.m-imagegrid > div > figure:last-child > a > figcaption { - border-right-width: 0; -} -.m-imagegrid > div > figure > figcaption, -.m-imagegrid > div > figure > a > figcaption { - color: transparent; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - font-size: 0.75rem; -} -.m-imagegrid > div > figure > div::before, -.m-imagegrid > div > figure > figcaption::before, -.m-imagegrid > div > figure > a > div::before, -.m-imagegrid > div > figure > a > figcaption::before { - content: ''; - display: inline-block; - height: 100%; - vertical-align: bottom; - width: 0; -} -.m-imagegrid > div > figure:hover > figcaption, -.m-imagegrid > div > figure:hover > a > figcaption { - background: linear-gradient( - transparent 0%, - transparent 75%, - rgba(0, 0, 0, 0.85) 100% - ); - color: #ffffff; -} -.m-imagegrid > div > figure > img, -.m-imagegrid > div > figure > a > img { - width: 100%; - height: 100%; -} -.m-imagegrid > div::after { - display: block; - content: ' '; - clear: both; -} -@media screen and (max-width: 767px) { - .m-imagegrid > div > figure { - float: none; - width: 100% !important; - } - .m-imagegrid > div > figure > div, - .m-imagegrid > div > figure > figcaption, - .m-imagegrid > div > figure > a > div, - .m-imagegrid > div > figure > a > figcaption { - border-left-width: 0; - border-right-width: 0; - } -} -.m-container-inflatable > .m-row > [class*='m-col-'] > .m-note, -.m-container-inflatable > .m-row > [class*='m-col-'] > .m-frame, -.m-container-inflatable > .m-row > [class*='m-col-'] > .m-block, -.m-container-inflatable > .m-row > [class*='m-col-'] > .m-imagegrid, -.m-container-inflatable > .m-row > [class*='m-col-'] > pre, -.m-container-inflatable > .m-row > [class*='m-col-'] > .m-code-figure, -.m-container-inflatable > .m-row > [class*='m-col-'] > .m-console-figure, -.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-note, -.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-frame, -.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-block, -.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-imagegrid, -.m-container-inflatable > .m-row > [class*='m-col-'] section > pre, -.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-code-figure, -.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-console-figure, -.m-container-inflatable [class*='m-center-'] > .m-note, -.m-container-inflatable [class*='m-center-'] > .m-frame, -.m-container-inflatable [class*='m-center-'] > .m-block, -.m-container-inflatable [class*='m-center-'] > .m-imagegrid, -.m-container-inflatable [class*='m-center-'] > pre, -.m-container-inflatable [class*='m-center-'] > .m-code-figure, -.m-container-inflatable [class*='m-center-'] > .m-console-figure, -.m-container-inflatable [class*='m-left-'] > .m-note, -.m-container-inflatable [class*='m-left-'] > .m-frame, -.m-container-inflatable [class*='m-left-'] > .m-block, -.m-container-inflatable [class*='m-left-'] > .m-imagegrid, -.m-container-inflatable [class*='m-left-'] > pre, -.m-container-inflatable [class*='m-left-'] > .m-code-figure, -.m-container-inflatable [class*='m-left-'] > .m-console-figure, -.m-container-inflatable [class*='m-right-'] > .m-note, -.m-container-inflatable [class*='m-right-'] > .m-frame, -.m-container-inflatable [class*='m-right-'] > .m-block, -.m-container-inflatable [class*='m-right-'] > .m-imagegrid, -.m-container-inflatable [class*='m-right-'] > pre, -.m-container-inflatable [class*='m-right-'] > .m-code-figure, -.m-container-inflatable [class*='m-right-'] > .m-console-figure, -.m-container-inflatable .m-container-inflate > .m-note, -.m-container-inflatable .m-container-inflate > .m-frame, -.m-container-inflatable .m-container-inflate > .m-block, -.m-container-inflatable .m-container-inflate > .m-imagegrid, -.m-container-inflatable .m-container-inflate > pre, -.m-container-inflatable .m-container-inflate > .m-code-figure, -.m-container-inflatable .m-container-inflate > .m-console-figure { - margin-left: -1rem; - margin-right: -1rem; -} -@media screen and (min-width: 576px) { - .m-container-inflatable .m-center-s > .m-note, - .m-container-inflatable .m-center-s > .m-frame, - .m-container-inflatable .m-center-s > .m-block, - .m-container-inflatable .m-center-s > .m-imagegrid, - .m-container-inflatable .m-center-s > pre, - .m-container-inflatable .m-center-s > .m-code-figure, - .m-container-inflatable .m-center-s > .m-console-figure { - margin-left: -1rem; - margin-right: -1rem; - } - .m-container-inflatable .m-left-s > .m-note, - .m-container-inflatable .m-left-s > .m-frame, - .m-container-inflatable .m-left-s > .m-block, - .m-container-inflatable .m-left-s > .m-imagegrid, - .m-container-inflatable .m-left-s > pre, - .m-container-inflatable .m-left-s > .m-code-figure, - .m-container-inflatable .m-left-s > .m-console-figure { - margin-left: -1rem; - margin-right: 0; - } - .m-container-inflatable .m-right-s > .m-note, - .m-container-inflatable .m-right-s > .m-frame, - .m-container-inflatable .m-right-s > .m-block, - .m-container-inflatable .m-right-s > .m-imagegrid, - .m-container-inflatable .m-right-s > pre, - .m-container-inflatable .m-right-s > .m-code-figure, - .m-container-inflatable .m-right-s > .m-console-figure { - margin-left: 0; - margin-right: -1rem; - } - .m-container-inflatable > .m-row > .m-col-s-10 > .m-imagegrid.m-container-inflate, - .m-container-inflatable - > .m-row - > .m-col-s-10 - section - > .m-imagegrid.m-container-inflate { - margin-left: -10%; - margin-right: -10%; - } -} -@media screen and (min-width: 768px) { - .m-container-inflatable .m-center-m > .m-note, - .m-container-inflatable .m-center-m > .m-frame, - .m-container-inflatable .m-center-m > .m-block, - .m-container-inflatable .m-center-m > .m-imagegrid, - .m-container-inflatable .m-center-m > pre, - .m-container-inflatable .m-center-m > .m-code-figure, - .m-container-inflatable .m-center-m > .m-console-figure { - margin-left: -1rem; - margin-right: -1rem; - } - .m-container-inflatable .m-left-m > .m-note, - .m-container-inflatable .m-left-m > .m-frame, - .m-container-inflatable .m-left-m > .m-block, - .m-container-inflatable .m-left-m > .m-imagegrid, - .m-container-inflatable .m-left-m > pre, - .m-container-inflatable .m-left-m > .m-code-figure, - .m-container-inflatable .m-left-m > .m-console-figure { - margin-left: -1rem; - margin-right: 0; - } - .m-container-inflatable .m-right-m > .m-note, - .m-container-inflatable .m-right-m > .m-frame, - .m-container-inflatable .m-right-m > .m-block, - .m-container-inflatable .m-right-m > .m-imagegrid, - .m-container-inflatable .m-right-m > pre, - .m-container-inflatable .m-right-m > .m-code-figure, - .m-container-inflatable .m-right-m > .m-console-figure { - margin-left: 0; - margin-right: -1rem; - } - .m-container-inflatable > .m-row > .m-col-m-10 > .m-imagegrid.m-container-inflate, - .m-container-inflatable - > .m-row - > .m-col-m-10 - section - > .m-imagegrid.m-container-inflate { - margin-left: -10%; - margin-right: -10%; - } -} -@media screen and (min-width: 992px) { - .m-container-inflatable .m-center-l > .m-note, - .m-container-inflatable .m-center-l > .m-frame, - .m-container-inflatable .m-center-l > .m-block, - .m-container-inflatable .m-center-l > .m-imagegrid, - .m-container-inflatable .m-center-l > pre, - .m-container-inflatable .m-center-l > .m-code-figure, - .m-container-inflatable .m-center-l > .m-console-figure { - margin-left: -1rem; - margin-right: -1rem; - } - .m-container-inflatable .m-left-l > .m-note, - .m-container-inflatable .m-left-l > .m-frame, - .m-container-inflatable .m-left-l > .m-block, - .m-container-inflatable .m-left-l > .m-imagegrid, - .m-container-inflatable .m-left-l > pre, - .m-container-inflatable .m-left-l > .m-code-figure, - .m-container-inflatable .m-left-l > .m-console-figure { - margin-left: -1rem; - margin-right: 0; - } - .m-container-inflatable .m-right-l > .m-note, - .m-container-inflatable .m-right-l > .m-frame, - .m-container-inflatable .m-right-l > .m-block, - .m-container-inflatable .m-right-l > .m-imagegrid, - .m-container-inflatable .m-right-l > pre, - .m-container-inflatable .m-right-l > .m-code-figure, - .m-container-inflatable .m-right-l > .m-console-figure { - margin-left: 0; - margin-right: -1rem; - } - .m-container-inflatable > .m-row > .m-col-l-10 > .m-imagegrid.m-container-inflate, - .m-container-inflatable - > .m-row - > .m-col-l-10 - section - > .m-imagegrid.m-container-inflate { - margin-left: -10%; - margin-right: -10%; - } -} -pre.m-code span.hll { - margin-left: -1rem; - margin-right: -1rem; - padding-left: 1rem; -} -.m-code.m-inverted > span, -.m-console.m-inverted > span { - opacity: 0.3333; -} -.m-code.m-inverted > span.hll, -.m-console.m-inverted > span.hll { - opacity: 1; - background-color: transparent; - border-color: transparent; -} -.m-code.m-inverted { - color: rgba(91, 91, 91, 0.33); -} -.m-console.m-inverted { - color: rgba(91, 91, 91, 0.33); -} -.m-code.m-inverted > span.hll { - color: #000000; -} -.m-cosole.m-inverted > span.hll { - color: #000000; -} -.m-code-color { - display: inline-block; - width: 0.75rem; - height: 0.75rem; - vertical-align: -0.05rem; - margin-left: 0.2rem; - margin-right: 0.1rem; - border-radius: 0px; -} -div.m-math { - overflow-x: auto; - overflow-y: hidden; -} -div.m-math svg { - margin-left: auto; - margin-right: auto; - display: block; -} -div.m-button a svg.m-math { - fill: #ffffff; -} -div.m-button.m-flat a svg.m-math { - fill: #000000; -} -div.m-button.m-flat a:hover svg.m-math, -div.m-button.m-default a:focus svg.m-math, -div.m-button.m-default a:active svg.m-math { - fill: #26a9e0; -} -.m-graph { - font-size: 14px; -} -div.m-plot svg, -div.m-graph svg { - max-width: 100%; - margin-left: auto; - margin-right: auto; - display: block; -} -div.m-plot .m-background { - fill: #fbf0ec; -} -div.m-plot svg .m-label { - font-size: 11px; -} -div.m-plot svg .m-title { - font-size: 13px; -} -div.m-plot svg .m-label, -div.m-plot svg .m-title { - fill: #000000; -} -div.m-plot svg .m-line { - stroke: #000000; - stroke-width: 0.8; -} -div.m-plot svg .m-error { - stroke: #000000; - stroke-width: 1.5; -} -div.m-plot svg .m-label.m-dim { - fill: #666; -} -.m-graph g.m-edge path, -.m-graph g.m-cluster polygon, -.m-graph g.m-node.m-flat ellipse, -.m-graph g.m-node.m-flat polygon { - fill: none; -} -.m-graph g.m-node:not(.m-flat) text { - fill: #ffffff; -} -figure.m-figure > svg.m-math:first-child, -figure.m-figure > svg.m-graph:first-child { - padding: 1rem; - box-sizing: content-box; -} -figure.m-figure:not(.m-flat) > svg.m-math:first-child, -figure.m-figure:not(.m-flat) > svg.m-graph:first-child { - background-color: #ddd; -} -.m-block.m-default { - border-left-color: #ddd; -} -.m-block.m-default h3, -.m-block.m-default h4, -.m-block.m-default h5, -.m-block.m-default h6, -.m-text.m-default, -.m-label.m-flat.m-default { - color: #000000; -} -.m-block.m-default h3 a, -.m-block.m-default h4 a, -.m-block.m-default h5 a, -.m-block.m-default h6 a { - color: #26a9e0; -} -.m-block.m-primary { - border-left-color: #31708f; -} -.m-block.m-primary h3, -.m-block.m-primary h4, -.m-block.m-primary h5, -.m-block.m-primary h6, -.m-block.m-primary h3 a, -.m-block.m-primary h4 a, -.m-block.m-primary h5 a, -.m-block.m-primary h6 a, -.m-text.m-primary, -.m-label.m-flat.m-primary { - color: #31708f; -} -.m-block.m-success { - border-left-color: #9ad36a; -} -.m-block.m-success h3, -.m-block.m-success h4, -.m-block.m-success h5, -.m-block.m-success h6, -.m-block.m-success h3 a, -.m-block.m-success h4 a, -.m-block.m-success h5 a, -.m-block.m-success h6 a, -.m-text.m-success, -.m-label.m-flat.m-success { - color: #9ad36a; -} -.m-block.m-warning { - border-left-color: #f9cf79; -} -.m-block.m-warning h3, -.m-block.m-warning h4, -.m-block.m-warning h5, -.m-block.m-warning h6, -.m-block.m-warning h3 a, -.m-block.m-warning h4 a, -.m-block.m-warning h5 a, -.m-block.m-warning h6 a, -.m-text.m-warning, -.m-label.m-flat.m-warning { - color: #f9cf79; -} -.m-block.m-danger { - border-left-color: #f60000; -} -.m-block.m-danger h3, -.m-block.m-danger h4, -.m-block.m-danger h5, -.m-block.m-danger h6, -.m-block.m-danger h3 a, -.m-block.m-danger h4 a, -.m-block.m-danger h5 a, -.m-block.m-danger h6 a, -.m-text.m-danger, -.m-label.m-flat.m-danger { - color: #f60000; -} -.m-block.m-info { - border-left-color: #31708f; -} -.m-block.m-info h3, -.m-block.m-info h4, -.m-block.m-info h5, -.m-block.m-info h6, -.m-block.m-info h3 a, -.m-block.m-info h4 a, -.m-block.m-info h5 a, -.m-block.m-info h6 a, -.m-text.m-info, -.m-label.m-flat.m-info { - color: #31708f; -} -.m-block.m-param h3, -.m-block.m-param h4, -.m-block.m-param h5, -.m-block.m-param h6, -.m-block.m-param h3 a, -.m-block.m-param h4 a, -.m-block.m-param h5 a, -.m-block.m-param h6 a, -.m-text.m-param, -.m-label.m-flat.m-param { - color: #9ad36a; -} -.m-block.m-dim { - border-left-color: #666; -} -span.m-default { - color: #000000; - background-color: transparent; -} -span.m-default a { - color: var(--default-link-color); - background-color: transparent; -} -span.m-default a:hover, -span.m-default a:focus, -span.m-default a:active { - color: #26a9e0; - background-color: transparent; -} -span.m-primary { - color: #31708f; - background-color: transparent; -} -span.m-primary a { - color: var(--primary-link-color); - background-color: transparent; -} -span.m-primary a:hover, -span.m-primary a:focus, -span.m-primary a:active { - color: #31708f; - background-color: transparent; -} -span.m-success { - color: #9ad36a; - background-color: transparent; -} -span.m-success a { - color: var(--success-link-color); - background-color: transparent; -} -span.m-success a:hover, -span.m-success a:focus, -span.m-success a:active { - color: #9ad36a; - background-color: transparent; -} -span.m-warning { - color: #f9cf79; - background-color: transparent; -} -span.m-warning a { - color: var(--warning-link-color); - background-color: transparent; -} -span.m-warning a:hover, -span.m-warning a:focus, -span.m-warning a:active { - color: #f9cf79; - background-color: transparent; -} -span.m-danger { - color: #f60000; - background-color: transparent; -} -span.m-danger a { - color: var(--danger-link-color); - background-color: transparent; -} -span.m-danger a:hover, -span.m-danger a:focus, -span.m-danger a:active { - color: #f60000; - background-color: transparent; -} -span.m-info { - color: #31708f; - background-color: transparent; -} -span.m-info a { - color: var(--info-link-color); - background-color: transparent; -} -span.m-info a:hover, -span.m-info a:focus, -span.m-info a:active { - color: #67cce0; - background-color: transparent; -} -span.m-param { - color: #9ad36a; - background-color: transparent; - font-weight: bold; -} -span.m-param a { - color: var(--param-link-color); - background-color: transparent; -} -span.m-param a:hover, -span.m-param a:focus, -span.m-param a:active { - color: #9ad36a; - background-color: transparent; -} -span.m-dim { - color: #666; - background-color: transparent; -} -span.m-dim a { - color: #949494; - background-color: transparent; -} -span.m-dim a:hover, -span.m-dim a:focus, -span.m-dim a:active { - color: #949494; - background-color: transparent; -} -.m-block.m-dim, -.m-text.m-dim, -.m-label.m-flat.m-dim { - color: #666; -} -.m-block.m-dim a, -.m-text.m-dim a { - color: #949494; -} -.m-block.m-dim a:hover, -.m-block.m-dim a:focus, -.m-block.m-dim a:active, -.m-text.m-dim a:hover, -.m-text.m-dim a:focus, -.m-text.m-dim a:active { - color: #949494; -} -.m-block.m-param { - border-left-color: #9ad36a; -} -.m-block.m-param h3, -.m-block.m-param h4, -.m-block.m-param h5, -.m-block.m-param h6, -.m-block.m-param h3 a, -.m-block.m-param h4 a, -.m-block.m-param h5 a, -.m-block.m-param h6 a, -.m-text.m-param, -.m-label.m-flat.m-param { - color: #9ad36a; -} -.m-block.m-flat { - border-color: transparent; -} -.m-block.m-flat h3, -.m-block.m-flat h4, -.m-block.m-flat h5, -.m-block.m-flat h6 { - color: #000000; -} -.m-block.m-default h3 a:hover, -.m-block.m-default h3 a:focus, -.m-block.m-default h3 a:active, -.m-block.m-default h4 a:hover, -.m-block.m-default h4 a:focus, -.m-block.m-default h4 a:active, -.m-block.m-default h5 a:hover, -.m-block.m-default h5 a:focus, -.m-block.m-default h5 a:active, -.m-block.m-default h6 a:hover, -.m-block.m-default h6 a:focus, -.m-block.m-default h6 a:active { - color: #26a9e0; -} -.m-block.m-primary h3 a:hover, -.m-block.m-primary h3 a:focus, -.m-block.m-primary h3 a:active, -.m-block.m-primary h4 a:hover, -.m-block.m-primary h4 a:focus, -.m-block.m-primary h4 a:active, -.m-block.m-primary h5 a:hover, -.m-block.m-primary h5 a:focus, -.m-block.m-primary h5 a:active, -.m-block.m-primary h6 a:hover, -.m-block.m-primary h6 a:focus, -.m-block.m-primary h6 a:active { - color: #31708f; -} -.m-block.m-success h3 a:hover, -.m-block.m-success h3 a:focus, -.m-block.m-success h3 a:active, -.m-block.m-success h4 a:hover, -.m-block.m-success h4 a:focus, -.m-block.m-success h4 a:active, -.m-block.m-success h5 a:hover, -.m-block.m-success h5 a:focus, -.m-block.m-success h5 a:active, -.m-block.m-success h6 a:hover, -.m-block.m-success h6 a:focus, -.m-block.m-success h6 a:active { - color: #9ad36a; -} -.m-block.m-warning h3 a:hover, -.m-block.m-warning h3 a:focus, -.m-block.m-warning h3 a:active, -.m-block.m-warning h4 a:hover, -.m-block.m-warning h4 a:focus, -.m-block.m-warning h4 a:active, -.m-block.m-warning h5 a:hover, -.m-block.m-warning h5 a:focus, -.m-block.m-warning h5 a:active, -.m-block.m-warning h6 a:hover, -.m-block.m-warning h6 a:focus, -.m-block.m-warning h6 a:active { - color: #f9cf79; -} -.m-block.m-danger h3 a:hover, -.m-block.m-danger h3 a:focus, -.m-block.m-danger h3 a:active, -.m-block.m-danger h4 a:hover, -.m-block.m-danger h4 a:focus, -.m-block.m-danger h4 a:active, -.m-block.m-danger h5 a:hover, -.m-block.m-danger h5 a:focus, -.m-block.m-danger h5 a:active, -.m-block.m-danger h6 a:hover, -.m-block.m-danger h6 a:focus, -.m-block.m-danger h6 a:active { - color: #f60000; -} -.m-block.m-info h3 a:hover, -.m-block.m-info h3 a:focus, -.m-block.m-info h3 a:active, -.m-block.m-info h4 a:hover, -.m-block.m-info h4 a:focus, -.m-block.m-info h4 a:active, -.m-block.m-info h5 a:hover, -.m-block.m-info h5 a:focus, -.m-block.m-info h5 a:active, -.m-block.m-info h6 a:hover, -.m-block.m-info h6 a:focus, -.m-block.m-info h6 a:active { - color: #67cce0; -} -.m-block.m-param h3 a:hover, -.m-block.m-param h3 a:focus, -.m-block.m-param h3 a:active, -.m-block.m-param h4 a:hover, -.m-block.m-param h4 a:focus, -.m-block.m-param h4 a:active, -.m-block.m-param h5 a:hover, -.m-block.m-param h5 a:focus, -.m-block.m-param h5 a:active, -.m-block.m-param h6 a:hover, -.m-block.m-param h6 a:focus, -.m-block.m-param h6 a:active { - color: #9ad36a; -} -.m-block.m-type h3 a:hover, -.m-block.m-type h3 a:focus, -.m-block.m-type h3 a:active, -.m-block.m-type h4 a:hover, -.m-block.m-type h4 a:focus, -.m-block.m-type h4 a:active, -.m-block.m-type h5 a:hover, -.m-block.m-type h5 a:focus, -.m-block.m-type h5 a:active, -.m-block.m-type h6 a:hover, -.m-block.m-type h6 a:focus, -.m-block.m-type h6 a:active { - color: var(--type-link-active-color); -} -div.m-button a, -.m-label { - color: #ffffff; -} -div.m-button.m-flat a { - color: #000000; -} -div.m-button.m-flat a:hover, -div.m-button.m-default a:focus, -div.m-button.m-default a:active { - color: #26a9e0; -} -div.m-button.m-default a, -.m-label:not(.m-flat).m-default { - background-color: #000000; - color: #353535; -} -div.m-button.m-primary a, -.m-label:not(.m-flat).m-primary { - background-color: #31708f; - color: #67cce0; -} -div.m-button.m-success a, -.m-label:not(.m-flat).m-success { - background-color: #9ad36a; - color: #3c763d; -} -div.m-button.m-warning a, -.m-label:not(.m-flat).m-warning { - background-color: #f9cf79; - color: #8a6d3b; -} -div.m-button.m-danger a, -.m-label:not(.m-flat).m-danger { - background-color: #f60000; - color: #920000; -} -div.m-button.m-info a, -.m-label:not(.m-flat).m-info { - background-color: #31708f; - color: #5dc1ed; -} -div.m-button.m-dim a, -.m-label:not(.m-flat).m-dim { - background-color: #666; - color: #9e9d9d; -} -div.m-button.m-param a, -.m-label:not(.m-flat).m-param { - background-color: #9ad36a; - color: #3c763d; -} -div.m-button.m-type a, -.m-label:not(.m-flat).m-type { - background-color: var(--type-color); - color: var(--type-filled-color); -} -div.m-button.m-default a:hover, -div.m-button.m-default a:focus, -div.m-button.m-default a:active { - background-color: #26a9e0; -} -div.m-button.m-primary a:hover, -div.m-button.m-primary a:focus, -div.m-button.m-primary a:active { - background-color: #31708f; -} -div.m-button.m-success a:hover, -div.m-button.m-success a:focus, -div.m-button.m-success a:active { - background-color: #9ad36a; -} -div.m-button.m-warning a:hover, -div.m-button.m-warning a:focus, -div.m-button.m-warning a:active { - background-color: #f9cf79; -} -div.m-button.m-danger a:hover, -div.m-button.m-danger a:focus, -div.m-button.m-danger a:active { - background-color: #f60000; -} -div.m-button.m-info a:hover, -div.m-button.m-info a:focus, -div.m-button.m-info a:active { - background-color: #67cce0; -} -div.m-button.m-dim a:hover, -div.m-button.m-dim a:focus, -div.m-button.m-dim a:active { - background-color: #c0c0c0; -} -div.m-button.m-param a:hover, -div.m-button.m-param a:focus, -div.m-button.m-param a:active { - background-color: #9ad36a; -} -div.m-button.m-type a:hover, -div.m-button.m-type a:focus, -div.m-button.m-type a:active { - background-color: var(--type-link-active-color); -} -.m-note.m-default { - background-color: transparent; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-default, -table.m-table tr.m-default td, -table.m-table td.m-default, -table.m-table tr.m-default th, -table.m-table th.m-default, -table.m-table tr.m-default strong, -table.m-table strong.m-default, -table.m-table tr.m-default em, -table.m-table em.m-default { - color: #353535; -} -.m-note.m-default a:hover, -table.m-table tr.m-default td a:hover, -table.m-table td.m-default a:hover, -table.m-table tr.m-default th a:hover, -table.m-table th.m-default a:hover, -.m-note.m-default a:focus, -table.m-table tr.m-default td a:focus, -table.m-table td.m-default a:focus, -table.m-table tr.m-default th a:focus, -table.m-table th.m-default a:focus, -.m-note.m-default a:active, -table.m-table tr.m-default td a:active, -table.m-table td.m-default a:active, -table.m-table tr.m-default th a:active, -table.m-table th.m-default a:active { - color: #26a9e0; -} -.m-note.m-primary { - border-color: #31708f; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-primary a, -table.m-table tr.m-primary td a, -table.m-table td.m-primary a, -table.m-table tr.m-primary th a, -table.m-table th.m-primary a { - color: #26a9e0; -} -.m-note.m-primary, -table.m-table tr.m-primary td, -table.m-table td.m-primary, -table.m-table tr.m-primary th, -table.m-table th.m-primary, -table.m-table tr.m-primary strong, -table.m-table strong.m-primary, -table.m-table tr.m-primary em, -table.m-table em.m-primary { - background-color: transparent; - color: #67cce0; -} -.m-note.m-primary a, -table.m-table tr.m-primary td a, -table.m-table td.m-primary a, -table.m-table tr.m-primary th a, -table.m-table th.m-primary a { - color: #31708f; -} -.m-note.m-primary a:hover, -table.m-table tr.m-primary td a:hover, -table.m-table td.m-primary a:hover, -table.m-table tr.m-primary th a:hover, -table.m-table th.m-primary a:hover, -.m-note.m-primary a:focus, -table.m-table tr.m-primary td a:focus, -table.m-table td.m-primary a:focus, -table.m-table tr.m-primary th a:focus, -table.m-table th.m-primary a:focus, -.m-note.m-primary a:active, -table.m-table tr.m-primary td a:active, -table.m-table td.m-primary a:active, -table.m-table tr.m-primary th a:active, -table.m-table th.m-primary a:active { - color: #31708f; -} -.m-note.m-success { - border-color: #9ad36a; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-success, -table.m-table tr.m-success td, -table.m-table td.m-success, -table.m-table tr.m-success th, -table.m-table th.m-success, -table.m-table tr.m-success strong, -table.m-table strong.m-success, -table.m-table tr.m-success em, -table.m-table em.m-success { - background-color: transparent; - color: #3c763d; -} -.m-note.m-success a, -table.m-table tr.m-success td a, -table.m-table td.m-success a, -table.m-table tr.m-success th a, -table.m-table th.m-success a { - color: #9ad36a; -} -.m-note.m-success a:hover, -table.m-table tr.m-success td a:hover, -table.m-table td.m-success a:hover, -table.m-table tr.m-success th a:hover, -table.m-table th.m-success a:hover, -.m-note.m-success a:focus, -table.m-table tr.m-success td a:focus, -table.m-table td.m-success a:focus, -table.m-table tr.m-success th a:focus, -table.m-table th.m-success a:focus, -.m-note.m-success a:active, -table.m-table tr.m-success td a:active, -table.m-table td.m-success a:active, -table.m-table tr.m-success th a:active, -table.m-table th.m-success a:active { - color: #9ad36a; -} -.m-note.m-warning { - border-color: #f9cf79; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-warning, -table.m-table tr.m-warning td, -table.m-table td.m-warning, -table.m-table tr.m-warning th, -table.m-table th.m-warning, -table.m-table tr.m-warning strong, -table.m-table strong.m-warning, -table.m-table tr.m-warning em, -table.m-table em.m-warning { - background-color: transparent; - color: #8a6d3b; -} -.m-note.m-warning a, -table.m-table tr.m-warning td a, -table.m-table td.m-warning a, -table.m-table tr.m-warning th a, -table.m-table th.m-warning a { - color: #f9cf79; -} -.m-note.m-warning a:hover, -table.m-table tr.m-warning td a:hover, -table.m-table td.m-warning a:hover, -table.m-table tr.m-warning th a:hover, -table.m-table th.m-warning a:hover, -.m-note.m-warning a:focus, -table.m-table tr.m-warning td a:focus, -table.m-table td.m-warning a:focus, -table.m-table tr.m-warning th a:focus, -table.m-table th.m-warning a:focus, -.m-note.m-warning a:active, -table.m-table tr.m-warning td a:active, -table.m-table td.m-warning a:active, -table.m-table tr.m-warning th a:active, -table.m-table th.m-warning a:active { - color: #f9cf79; -} -.m-note.m-danger { - border-color: #f60000; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-danger, -table.m-table tr.m-danger td, -table.m-table td.m-danger, -table.m-table tr.m-danger th, -table.m-table th.m-danger, -table.m-table tr.m-danger strong, -table.m-table strong.m-danger, -table.m-table tr.m-danger em, -table.m-table em.m-danger { - background-color: transparent; - color: #920000; -} -.m-note.m-danger a, -table.m-table tr.m-danger td a, -table.m-table td.m-danger a, -table.m-table tr.m-danger th a, -table.m-table th.m-danger a { - color: #f60000; -} -.m-note.m-danger a:hover, -table.m-table tr.m-danger td a:hover, -table.m-table td.m-danger a:hover, -table.m-table tr.m-danger th a:hover, -table.m-table th.m-danger a:hover, -.m-note.m-danger a:focus, -table.m-table tr.m-danger td a:focus, -table.m-table td.m-danger a:focus, -table.m-table tr.m-danger th a:focus, -table.m-table th.m-danger a:focus, -.m-note.m-danger a:active, -table.m-table tr.m-danger td a:active, -table.m-table td.m-danger a:active, -table.m-table tr.m-danger th a:active, -table.m-table th.m-danger a:active { - color: #f60000; -} -.m-note.m-info { - border-color: #31708f; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-info, -table.m-table tr.m-info td, -table.m-table td.m-info, -table.m-table tr.m-info th, -table.m-table th.m-info, -table.m-table tr.m-info strong, -table.m-table strong.m-info, -table.m-table tr.m-info em, -table.m-table em.m-info { - background-color: transparent; - color: #5dc1ed; -} -.m-note.m-info a, -table.m-table tr.m-info td a, -table.m-table td.m-info a, -table.m-table tr.m-info th a, -table.m-table th.m-info a { - color: #67cce0; -} -.m-note.m-info a:hover, -table.m-table tr.m-info td a:hover, -table.m-table td.m-info a:hover, -table.m-table tr.m-info th a:hover, -table.m-table th.m-info a:hover, -.m-note.m-info a:focus, -table.m-table tr.m-info td a:focus, -table.m-table td.m-info a:focus, -table.m-table tr.m-info th a:focus, -table.m-table th.m-info a:focus, -.m-note.m-info a:active, -table.m-table tr.m-info td a:active, -table.m-table td.m-info a:active, -table.m-table tr.m-info th a:active, -table.m-table th.m-info a:active { - color: #67cce0; -} -.m-note.m-dim { - border-color: #666; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-dim, -table.m-table tr.m-dim td, -table.m-table td.m-dim, -table.m-table tr.m-dim th, -table.m-table th.m-dim, -table.m-table tr.m-dim strong, -table.m-table strong.m-dim, -table.m-table tr.m-dim em, -table.m-table em.m-dim { - background-color: transparent; - color: #9e9d9d; -} -.m-note.m-dim a, -table.m-table tr.m-dim td a, -table.m-table td.m-dim a, -table.m-table tr.m-dim th a, -table.m-table th.m-dim a { - color: #c0c0c0; -} -.m-note.m-dim a:hover, -table.m-table tr.m-dim td a:hover, -table.m-table td.m-dim a:hover, -table.m-table tr.m-dim th a:hover, -table.m-table th.m-dim a:hover, -.m-note.m-dim a:focus, -table.m-table tr.m-dim td a:focus, -table.m-table td.m-dim a:focus, -table.m-table tr.m-dim th a:focus, -table.m-table th.m-dim a:focus, -.m-note.m-dim a:active, -table.m-table tr.m-dim td a:active, -table.m-table td.m-dim a:active, -table.m-table tr.m-dim th a:active, -table.m-table th.m-dim a:active { - color: #c0c0c0; -} -.m-note.m-param { - border-color: #9ad36a; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-param, -table.m-table tr.m-param td, -table.m-table td.m-param, -table.m-table tr.m-param th, -table.m-table th.m-param, -table.m-table tr.m-param strong, -table.m-table strong.m-param, -table.m-table tr.m-param em, -table.m-table em.m-param { - background-color: transparent; - color: #3c763d; -} -.m-note.m-param a, -table.m-table tr.m-param td a, -table.m-table td.m-param a, -table.m-table tr.m-param th a, -table.m-table th.m-param a { - color: #9ad36a; -} -.m-note.m-param a:hover, -table.m-table tr.m-param td a:hover, -table.m-table td.m-param a:hover, -table.m-table tr.m-param th a:hover, -table.m-table th.m-param a:hover, -.m-note.m-param a:focus, -table.m-table tr.m-param td a:focus, -table.m-table td.m-param a:focus, -table.m-table tr.m-param th a:focus, -table.m-table th.m-param a:focus, -.m-note.m-param a:active, -table.m-table tr.m-param td a:active, -table.m-table td.m-param a:active, -table.m-table tr.m-param th a:active, -table.m-table th.m-param a:active { - color: #9ad36a; -} -.m-note.m-type, -table.m-table tr.m-type td, -table.m-table td.m-type, -table.m-table tr.m-type th, -table.m-table th.m-type { - background-color: var(--type-filled-background-color); - color: var(--type-filled-color); -} -.m-note.m-type a, -table.m-table tr.m-type td a, -table.m-table td.m-type a, -table.m-table tr.m-type th a, -table.m-table th.m-type a { - color: var(--type-filled-link-color); -} -.m-note.m-type a:hover, -table.m-table tr.m-type td a:hover, -table.m-table td.m-type a:hover, -table.m-table tr.m-type th a:hover, -table.m-table th.m-type a:hover, -.m-note.m-type a:focus, -table.m-table tr.m-type td a:focus, -table.m-table td.m-type a:focus, -table.m-table tr.m-type th a:focus, -table.m-table th.m-type a:focus, -.m-note.m-type a:active, -table.m-table tr.m-type td a:active, -table.m-table td.m-type a:active, -table.m-table tr.m-type th a:active, -table.m-table th.m-type a:active { - color: var(--type-filled-link-active-color); -} -figure.m-figure.m-default::before { - border-color: transparent; -} -figure.m-figure.m-default figcaption { - color: #000000; -} -figure.m-figure.m-primary::before { - border-color: transparent; -} -figure.m-figure.m-primary figcaption { - color: #31708f; -} -figure.m-figure.m-primary figcaption .m-figure-description { - color: #000000; -} -figure.m-figure.m-success::before { - border-color: transparent; -} -figure.m-figure.m-success figcaption { - color: #9ad36a; -} -figure.m-figure.m-success figcaption .m-figure-description { - color: #000000; -} -figure.m-figure.m-warning::before { - border-color: transparent; -} -figure.m-figure.m-warning figcaption { - color: #f9cf79; -} -figure.m-figure.m-warning figcaption .m-figure-description { - color: #000000; -} -figure.m-figure.m-danger::before { - border-color: transparent; -} -figure.m-figure.m-danger figcaption { - color: #f60000; -} -figure.m-figure.m-danger figcaption .m-figure-description { - color: #000000; -} -figure.m-figure.m-info::before { - border-color: transparent; -} -figure.m-figure.m-info figcaption { - color: #31708f; -} -figure.m-figure.m-info figcaption .m-figure-description { - color: #000000; -} -figure.m-figure.m-param::before { - border-color: transparent; -} -figure.m-figure.m-param figcaption { - color: #9ad36a; -} -figure.m-figure.m-type::before { - border-color: var(--type-filled-background-color); -} -figure.m-figure.m-type figcaption { - color: var(--type-color); -} -figure.m-figure.m-dim::before { - border-color: transparent; -} -figure.m-figure.m-dim { - color: #666; -} -figure.m-figure.m-dim a { - color: #949494; -} -figure.m-figure.m-dim a:hover, -figure.m-figure.m-dim a:focus, -figure.m-figure.m-dim a:active { - color: #949494; -} -.m-math { - fill: #000000; -} -.m-math.m-default, -.m-math g.m-default, -.m-math rect.m-default, -div.m-plot svg .m-bar.m-default, -.m-graph g.m-edge polygon, -.m-graph g.m-node:not(.m-flat) ellipse, -.m-graph g.m-node:not(.m-flat) polygon, -.m-graph g.m-edge text, -.m-graph g.m-node.m-flat text, -.m-graph g.m-cluster text, -.m-graph.m-default g.m-edge polygon, -.m-graph.m-default g.m-node:not(.m-flat) ellipse, -.m-graph.m-default g.m-node:not(.m-flat) polygon, -.m-graph.m-default g.m-edge text, -.m-graph.m-default g.m-node.m-flat text, -.m-graph.m-default g.m-cluster text { - fill: #000000; -} -.m-graph g.m-edge polygon, -.m-graph g.m-edge path, -.m-graph g.m-node ellipse, -.m-graph g.m-node polygon, -.m-graph g.m-node polyline, -.m-graph g.m-cluster polygon, -.m-graph.m-default g.m-edge polygon, -.m-graph.m-default g.m-edge path, -.m-graph.m-default g.m-node ellipse, -.m-graph.m-default g.m-node polygon, -.m-graph.m-default g.m-node polyline, -.m-graph.m-default g.m-cluster polygon { - stroke: #000000; -} -.m-math.m-primary, -.m-math g.m-primary, -.m-math rect.m-primary, -div.m-plot svg .m-bar.m-primary, -.m-graph.m-primary g.m-edge polygon, -.m-graph.m-primary g.m-node:not(.m-flat) ellipse, -.m-graph.m-primary g.m-node:not(.m-flat) polygon, -.m-graph.m-primary g.m-edge text, -.m-graph.m-primary g.m-node.m-flat text, -.m-graph.m-primary g.m-cluster text { - fill: #31708f; -} -.m-graph.m-primary g.m-edge polygon, -.m-graph.m-primary g.m-edge path, -.m-graph.m-primary g.m-node ellipse, -.m-graph.m-primary g.m-node polygon, -.m-graph.m-primary g.m-node polyline, -.m-graph.m-primary g.m-cluster polygon { - stroke: #31708f; -} -.m-math.m-success, -.m-math g.m-success, -.m-math rect.m-success, -div.m-plot svg .m-bar.m-success, -.m-graph.m-success g.m-edge polygon, -.m-graph.m-success g.m-node:not(.m-flat) ellipse, -.m-graph.m-success g.m-node:not(.m-flat) polygon, -.m-graph.m-success g.m-edge text, -.m-graph.m-success g.m-node.m-flat text, -.m-graph.m-success g.m-cluster text { - fill: #9ad36a; -} -.m-graph.m-success g.m-edge polygon, -.m-graph.m-success g.m-edge path, -.m-graph.m-success g.m-node ellipse, -.m-graph.m-success g.m-node polygon, -.m-graph.m-success g.m-node polyline, -.m-graph.m-success g.m-cluster polygon { - stroke: #9ad36a; -} -.m-math.m-warning, -.m-math g.m-warning, -.m-math rect.m-warning, -div.m-plot svg .m-bar.m-warning, -.m-graph.m-warning g.m-edge polygon, -.m-graph.m-warning g.m-node:not(.m-flat) ellipse, -.m-graph.m-warning g.m-node:not(.m-flat) polygon, -.m-graph.m-warning g.m-edge text, -.m-graph.m-warning g.m-node.m-flat text, -.m-graph.m-warning g.m-cluster text { - fill: #f9cf79; -} -.m-graph.m-warning g.m-edge polygon, -.m-graph.m-warning g.m-edge path, -.m-graph.m-warning g.m-node ellipse, -.m-graph.m-warning g.m-node polygon, -.m-graph.m-warning g.m-node polyline, -.m-graph.m-warning g.m-cluster polygon { - stroke: #f9cf79; -} -.m-math.m-danger, -.m-math g.m-danger, -.m-math rect.m-danger, -div.m-plot svg .m-bar.m-danger, -.m-graph.m-danger g.m-edge polygon, -.m-graph.m-danger g.m-node:not(.m-flat) ellipse, -.m-graph.m-danger g.m-node:not(.m-flat) polygon, -.m-graph.m-danger g.m-edge text, -.m-graph.m-danger g.m-node.m-flat text, -.m-graph.m-danger g.m-cluster text { - fill: #f60000; -} -.m-graph.m-danger g.m-edge polygon, -.m-graph.m-danger g.m-edge path, -.m-graph.m-danger g.m-node ellipse, -.m-graph.m-danger g.m-node polygon, -.m-graph.m-danger g.m-node polyline, -.m-graph.m-danger g.m-cluster polygon { - stroke: #f60000; -} -.m-math.m-info, -.m-math g.m-info, -.m-math rect.m-info, -div.m-plot svg .m-bar.m-info, -.m-graph.m-info g.m-edge polygon, -.m-graph.m-info g.m-node:not(.m-flat) ellipse, -.m-graph.m-info g.m-node:not(.m-flat) polygon, -.m-graph.m-info g.m-edge text, -.m-graph.m-info g.m-node.m-flat text, -.m-graph.m-info g.m-cluster text { - fill: #31708f; -} -.m-graph.m-info g.m-edge polygon, -.m-graph.m-info g.m-edge path, -.m-graph.m-info g.m-node ellipse, -.m-graph.m-info g.m-node polygon, -.m-graph.m-info g.m-node polyline, -.m-graph.m-info g.m-cluster polygon { - stroke: #31708f; -} -.m-math.m-dim, -.m-math g.m-dim, -.m-math rect.m-dim, -div.m-plot svg .m-bar.m-dim, -.m-graph.m-dim g.m-edge polygon, -.m-graph.m-dim g.m-node:not(.m-flat) ellipse, -.m-graph.m-dim g.m-node:not(.m-flat) polygon, -.m-graph.m-dim g.m-edge text, -.m-graph.m-dim g.m-node.m-flat text, -.m-graph.m-dim g.m-cluster text { - fill: #666; -} -.m-graph.m-dim g.m-edge polygon, -.m-graph.m-dim g.m-edge path, -.m-graph.m-dim g.m-node ellipse, -.m-graph.m-dim g.m-node polygon, -.m-graph.m-dim g.m-node polyline, -.m-graph.m-dim g.m-cluster polygon { - stroke: #666; -} -.m-math.m-param, -.m-math g.m-param, -.m-math rect.m-param, -div.m-plot svg .m-bar.m-param, -.m-graph.m-param g.m-edge polygon, -.m-graph.m-param g.m-node:not(.m-flat) ellipse, -.m-graph.m-param g.m-node:not(.m-flat) polygon, -.m-graph.m-param g.m-edge text, -.m-graph.m-param g.m-node.m-flat text { - fill: #9ad36a; -} -.m-graph.m-param g.m-edge polygon, -.m-graph.m-param g.m-edge path, -.m-graph.m-param g.m-node ellipse, -.m-graph.m-param g.m-node polygon, -.m-graph.m-param g.m-node polyline { - stroke: #9ad36a; -} -.m-math.m-type, -.m-math g.m-type, -.m-math rect.m-type, -div.m-plot svg .m-bar.m-type, -.m-graph.m-type g.m-edge polygon, -.m-graph.m-type g.m-node:not(.m-flat) ellipse, -.m-graph.m-type g.m-node:not(.m-flat) polygon, -.m-graph.m-type g.m-edge text, -.m-graph.m-type g.m-node.m-flat text { - fill: var(--type-color); -} -.m-graph.m-type g.m-edge polygon, -.m-graph.m-type g.m-edge path, -.m-graph.m-type g.m-node ellipse, -.m-graph.m-type g.m-node polygon, -.m-graph.m-type g.m-node polyline { - stroke: var(--type-color); -} -.m-graph g.m-edge.m-default polygon, -.m-graph g.m-node.m-default:not(.m-flat) ellipse, -.m-graph g.m-node.m-default:not(.m-flat) polygon, -.m-graph g.m-edge.m-default text, -.m-graph g.m-node.m-default.m-flat text, -.m-graph g.m-cluster.m-default text { - fill: #000000; -} -.m-graph g.m-edge.m-default polygon, -.m-graph g.m-edge.m-default path, -.m-graph g.m-node.m-default ellipse, -.m-graph g.m-node.m-default polygon, -.m-graph g.m-node.m-default polyline, -.m-graph g.m-cluster.m-default polygon { - stroke: #000000; -} -.m-graph g.m-edge.m-primary polygon, -.m-graph g.m-node.m-primary:not(.m-flat) ellipse, -.m-graph g.m-node.m-primary:not(.m-flat) polygon, -.m-graph g.m-edge.m-primary text, -.m-graph g.m-node.m-primary.m-flat text, -.m-graph g.m-cluster.m-primary text { - fill: #31708f; -} -.m-graph g.m-edge.m-primary polygon, -.m-graph g.m-edge.m-primary path, -.m-graph g.m-node.m-primary ellipse, -.m-graph g.m-node.m-primary polygon, -.m-graph g.m-node.m-primary polyline, -.m-graph g.m-cluster.m-primary polygon { - stroke: #31708f; -} -.m-graph g.m-edge.m-success polygon, -.m-graph g.m-node.m-success:not(.m-flat) ellipse, -.m-graph g.m-node.m-success:not(.m-flat) polygon, -.m-graph g.m-edge.m-success text, -.m-graph g.m-node.m-success.m-flat text, -.m-graph g.m-cluster.m-success text { - fill: #9ad36a; -} -.m-graph g.m-edge.m-success polygon, -.m-graph g.m-edge.m-success path, -.m-graph g.m-node.m-success ellipse, -.m-graph g.m-node.m-success polygon, -.m-graph g.m-node.m-success polyline, -.m-graph g.m-cluster.m-success polygon { - stroke: #9ad36a; -} -.m-graph g.m-edge.m-warning polygon, -.m-graph g.m-node.m-warning:not(.m-flat) ellipse, -.m-graph g.m-node.m-warning:not(.m-flat) polygon, -.m-graph g.m-edge.m-warning text, -.m-graph g.m-node.m-warning.m-flat text, -.m-graph g.m-cluster.m-warning text { - fill: #f9cf79; -} -.m-graph g.m-edge.m-warning polygon, -.m-graph g.m-edge.m-warning path, -.m-graph g.m-node.m-warning ellipse, -.m-graph g.m-node.m-warning polygon, -.m-graph g.m-node.m-warning polyline, -.m-graph g.m-cluster.m-warning polygon { - stroke: #f9cf79; -} -.m-graph g.m-edge.m-danger polygon, -.m-graph g.m-node.m-danger:not(.m-flat) ellipse, -.m-graph g.m-node.m-danger:not(.m-flat) polygon, -.m-graph g.m-edge.m-danger text, -.m-graph g.m-node.m-danger.m-flat text, -.m-graph g.m-cluster.m-danger text { - fill: #f60000; -} -.m-graph g.m-edge.m-danger polygon, -.m-graph g.m-edge.m-danger path, -.m-graph g.m-node.m-danger ellipse, -.m-graph g.m-node.m-danger polygon, -.m-graph g.m-node.m-danger polyline, -.m-graph g.m-cluster.m-danger polygon { - stroke: #f60000; -} -.m-graph g.m-edge.m-info polygon, -.m-graph g.m-node.m-info:not(.m-flat) ellipse, -.m-graph g.m-node.m-info:not(.m-flat) polygon, -.m-graph g.m-edge.m-info text, -.m-graph g.m-node.m-info.m-flat text, -.m-graph g.m-cluster.m-info text { - fill: #31708f; -} -.m-graph g.m-edge.m-info polygon, -.m-graph g.m-edge.m-info path, -.m-graph g.m-node.m-info ellipse, -.m-graph g.m-node.m-info polygon, -.m-graph g.m-node.m-info polyline, -.m-graph g.m-cluster.m-info polygon { - stroke: #31708f; -} -.m-graph g.m-edge.m-dim polygon, -.m-graph g.m-node.m-dim:not(.m-flat) ellipse, -.m-graph g.m-node.m-dim:not(.m-flat) polygon, -.m-graph g.m-edge.m-dim text, -.m-graph g.m-node.m-dim.m-flat text, -.m-graph g.m-cluster.m-dim text { - fill: #666; -} -.m-graph g.m-edge.m-dim polygon, -.m-graph g.m-edge.m-dim path, -.m-graph g.m-node.m-dim ellipse, -.m-graph g.m-node.m-dim polygon, -.m-graph g.m-node.m-dim polyline, -.m-graph g.m-cluster.m-dim polygon { - stroke: #666; -} -.m-graph g.m-edge.m-param polygon, -.m-graph g.m-node.m-param:not(.m-flat) ellipse, -.m-graph g.m-node.m-param:not(.m-flat) polygon, -.m-graph g.m-edge.m-param text, -.m-graph g.m-node.m-param.m-flat text { - fill: #9ad36a; -} -.m-graph g.m-edge.m-param polygon, -.m-graph g.m-edge.m-param path, -.m-graph g.m-node.m-param ellipse, -.m-graph g.m-node.m-param polygon, -.m-graph g.m-node.m-param polyline, -.m-graph g.m-cluster.m-param polygon { - stroke: #9ad36a; -} -.m-graph g.m-edge.m-type polygon, -.m-graph g.m-node.m-type:not(.m-flat) ellipse, -.m-graph g.m-node.m-type:not(.m-flat) polygon, -.m-graph g.m-edge.m-type text, -.m-graph g.m-node.m-type.m-flat text { - fill: var(--type-color); -} -.m-graph g.m-edge.m-type polygon, -.m-graph g.m-edge.m-type path, -.m-graph g.m-node.m-type ellipse, -.m-graph g.m-node.m-type polygon, -.m-graph g.m-node.m-type polyline, -.m-graph g.m-cluster.m-type polygon { - stroke: var(--type-color); -} -p, -ul, -ol, -dl, -blockquote, -pre, -.m-code-figure, -.m-console-figure, -hr, -.m-note, -.m-frame, -.m-block, -div.m-button, -div.m-scroll, -table.m-table, -div.m-image, -img.m-image, -svg.m-image, -figure.m-figure, -.m-imagegrid, -div.m-math, -div.m-graph, -div.m-plot { - margin-bottom: 1rem; -} -p:last-child, -p.m-nopadb, -ul:last-child, -ul.m-nopadb, -ol:last-child, -ol.m-nopadb, -dl:last-child, -dl.m-nopadb, -blockquote:last-child, -blockquote.m-nopadb, -pre:last-child, -pre.m-nopadb, -.m-code-figure:last-child, -.m-code-figure.m-nopadb, -.m-console-figure:last-child, -.m-console-figure.m-nopadb, -hr:last-child, -hr.m-nopadb, -.m-note:last-child, -.m-note.m-nopadb, -.m-frame:last-child, -.m-frame.m-nopadb, -.m-block:last-child, -.m-block.m-nopadb, -div.m-button:last-child, -div.m-button.m-nopadb, -div.m-scroll:last-child, -div.m-scroll.m-nopadb, -table.m-table:last-child, -table.m-table.m-nopadb, -img.m-image:last-child, -img.m-image.m-nopadb, -svg.m-image:last-child, -svg.m-image.m-nopadb, -div.m-image:last-child, -div.m-image.m-nopadb, -figure.m-figure:last-child, -figure.m-figure.m-nopadb, -.m-imagegrid:last-child, -.m-imagegrid.m-nopadb, -div.m-math:last-child, -div.m-math.m-nopadb, -div.m-graph:last-child, -div.m-graph.m-nopadb, -div.m-plot:last-child, -div.m-plot.m-nopadb { - margin-bottom: 0; -} -li > p:last-child, -li > blockquote:last-child, -li > pre:last-child, -li > .m-code-figure:last-child, -li > .m-console-figure:last-child, -li > .m-note:last-child, -li > .m-frame:last-child, -li > .m-block:last-child, -li > div.m-button:last-child, -li > div.m-scroll:last-child, -li > table.m-table:last-child, -li > img.m-image:last-child, -li > svg.m-image:last-child, -li > div.m-image:last-child, -li > figure.m-figure:last-child, -li > div.m-math:last-child, -li > div.m-graph:last-child, -li > div.m-plot:last-child { - margin-bottom: 1rem; -} -li:last-child > p:last-child, -li:last-child > p.m-nopadb, -li:last-child > blockquote:last-child, -li:last-child > blockquote.m-nopadb, -li:last-child > pre:last-child, -li:last-child > pre.m-nopadb, -li:last-child > .m-code-figure:last-child, -li:last-child > .m-code-figure.m-nopadb, -li:last-child > .m-console-figure:last-child, -li:last-child > .m-console-figure.m-nopadb, -li:last-child > .m-note:last-child, -li:last-child > .m-note.m-nopadb, -li:last-child > .m-frame:last-child, -li:last-child > .m-frame.m-nopadb, -li:last-child > .m-block:last-child, -li:last-child > .m-block.m-nopadb, -li:last-child > div.m-button:last-child, -li:last-child > div.m-button.m-nopadb, -li:last-child > div.m-scroll:last-child, -li:last-child > div.m-scroll.m-nopadb, -li:last-child > table.m-table:last-child, -li:last-child > table.m-table.m-nopadb, -li:last-child > img.m-image:last-child, -li:last-child > img.m-image.m-nopadb, -li:last-child > svg.m-image:last-child, -li:last-child > svg.m-image.m-nopadb, -li:last-child > div.m-image:last-child, -li:last-child > div.m-image.m-nopadb, -li:last-child > figure.m-figure:last-child, -li:last-child > figure.m-figure.m-nopadb, -li:last-child > div.m-math:last-child, -li:last-child > div.m-math.m-nopadb, -li:last-child > div.m-graph:last-child, -li:last-child > div.m-graph.m-nopadb, -li:last-child > div.m-plot:last-child, -li:last-child > div.m-plot.m-nopadb { - margin-bottom: 0; -} - -body > header > nav { - width: 100%; - background-color: #000000; - min-height: 3rem; - font-size: 16px; -} -body > header > nav.m-navbar-landing, -body > header > nav.m-navbar-cover { - background-color: transparent; - position: relative; -} -body > header > nav.m-navbar-landing { - opacity: 0.8; -} -body > header > nav.m-navbar-cover { - background-color: #000000; - opacity: 1; -} -body > header > nav.m-navbar-landing:hover, -body > header > nav.m-navbar-cover:hover { - background-color: #000000; - opacity: 1; -} -body > header > nav.m-navbar-landing:target, -body > header > nav.m-navbar-cover:target { - background-color: #000000; - opacity: 1; -} -body > header > nav.m-navbar-landing #m-navbar-brand.m-navbar-brand-hidden { - visibility: hidden; -} -body > header > nav.m-navbar-landing:target #m-navbar-brand.m-navbar-brand-hidden { - visibility: visible; -} -body > header > nav { - margin-left: auto; - margin-right: auto; - color: #ffffff; -} -body > header > nav a { - text-decoration: none; - text-transform: none; - display: inline-block; - vertical-align: middle; - line-height: 2.75rem; - color: #ffffff; -} -body > header > nav #m-navbar-brand, -body > header > nav a#m-navbar-show, -body > header > nav a#m-navbar-hide { - font-weight: 300; - font-size: 1.125rem; - padding-left: 1rem; - padding-right: 1rem; -} -body > header > nav a#m-navbar-brand, -body > header > nav #m-navbar-brand a { - text-transform: none; -} -body > header > nav a#m-navbar-brand img, -body > header > nav #m-navbar-brand a img { - height: 5rem; - vertical-align: -22.5%; - margin-right: 0.5rem; -} -body > header > nav #m-navbar-brand a { - padding-left: 0; - padding-right: 0; -} -body > header > nav #m-navbar-brand .m-thin { - font-weight: normal; -} -body > header > nav #m-navbar-brand .m-breadcrumb { - color: #bdbdbd; -} -body > header > nav a#m-navbar-show::before, -body > header > nav a#m-navbar-hide::before { - content: '\2630'; -} -body > header > nav #m-navbar-collapse { - padding-bottom: 1rem; -} -body > header > nav #m-navbar-collapse li { - border-style: solid; - border-color: transparent; - border-width: 0 0 0 0.25rem; - margin-left: -1rem; -} -body > header > nav #m-navbar-collapse li a { - border-style: solid; - border-color: transparent; - line-height: 1.5rem; - margin-left: -0.25rem; - padding-left: 0.75rem; - border-width: 0 1px 1px 1px; - width: 100%; -} -body > header > nav #m-navbar-collapse li ol { - border-color: #ddd; -} -body > header > nav #m-navbar-collapse li a#m-navbar-current { - color: #ffffff; - background-color: #000000; - border-color: #000000; -} -body > header > nav #m-navbar-collapse li ol li a#m-navbar-current { - color: #000000; - background-color: #ffffff; - border-color: #ddd; -} -body > header > nav ol { - list-style-type: none; - margin: 0; -} -body > header > nav ol ol { - padding-left: 1.5rem; -} -body > header > nav .m-row > [class*='m-col-'] { - padding-top: 0; - padding-bottom: 0; -} -body > header > nav a:hover, -body > header > nav a:focus, -body > header > nav a:active { - color: #ffffff; -} -body > header > nav #m-navbar-collapse li:hover { - border-color: #ffffff; -} -body > header > nav #m-navbar-collapse li a:hover, -body > header > nav #m-navbar-collapse li a:focus, -body > header > nav #m-navbar-collapse li a:active { - border-color: #ffffff; - background-color: #000000; -} -body > header > nav.m-navbar-landing #m-navbar-collapse li a:hover, -body > header > nav.m-navbar-cover #m-navbar-collapse li a:hover, -body > header > nav.m-navbar-landing #m-navbar-collapse li a:focus, -body > header > nav.m-navbar-cover #m-navbar-collapse li a:focus, -body > header > nav.m-navbar-landing #m-navbar-collapse li a:active, -body > header > nav.m-navbar-cover #m-navbar-collapse li a:active { - background-color: var(--header-link-active-background-color-semi); -} -body > header > nav #m-navbar-hide { - display: none; -} -body > header > nav:target #m-navbar-collapse { - display: block; -} -body > header > nav:target #m-navbar-show { - display: none; -} -body > header > nav:target #m-navbar-hide { - display: inline-block; -} -@media screen and (min-width: 768px) { - body > header > nav #m-navbar-show, - body > header > nav #m-navbar-hide, - body > header > nav:target #m-navbar-show, - body > header > nav:target #m-navbar-hide { - display: none; - } - body > header > nav #m-navbar-collapse li a { - line-height: 2.75rem; - } - body > header > nav a, - body > header > nav #m-navbar-collapse li a { - margin-left: 0; - padding-left: 1rem; - padding-right: 1rem; - white-space: nowrap; - } - body > header > nav #m-navbar-collapse { - padding-bottom: 0; - } - body > header > nav #m-navbar-collapse li ol { - background-color: #000000; - } - body > header > nav #m-navbar-collapse ol ol li { - margin-left: 0; - padding-left: 0; - border-left-width: 0; - } - body > header > nav #m-navbar-collapse ol ol li a { - padding-left: 0.75rem; - color: #000000; - background-color: #ffffff; - border-color: #ddd; - } - body > header > nav #m-navbar-collapse ol ol li a:active { - padding-left: 0.75rem; - color: #ffffff; - background-color: #353535; - border-color: #ddd; - } - body > header > nav #m-navbar-collapse ol ol li a:hover { - padding-left: 0.75rem; - color: #ffffff; - background-color: #353535; - border-color: #ddd; - } - body > header > nav #m-navbar-collapse > .m-row > ol > li { - margin-left: 0; - border-left-width: 0; - } - body > header > nav #m-navbar-collapse > .m-row > ol > li > a { - border-width: 0.25rem 0 0 0; - } - body > header > nav #m-navbar-collapse ol { - padding-left: 0; - padding-right: 0; - } - body > header > nav #m-navbar-collapse > .m-row > ol, - body > header > nav #m-navbar-collapse > .m-row > ol > li { - float: left; - } - body > header > nav #m-navbar-collapse ol ol { - z-index: 99999; - position: absolute; - visibility: hidden; - } - body > header > nav #m-navbar-collapse li:hover ol { - visibility: visible; - } -} -body > footer { - width: 100%; -} -body > footer > nav { - padding-top: 1rem; - padding-bottom: 1rem; - font-size: 0.85rem; - text-align: center; - color: #777777; - background-color: #353535; -} -body > footer > nav h3, -body > footer > nav h3 a { - text-transform: capitalize; - font-weight: normal; -} -body > footer > nav ul { - list-style-type: none; - padding: 0; - margin: 0; -} -body > footer > nav a { - text-decoration: none; - text-transform: none; - color: #999; -} -body > footer > nav a:hover, -body > footer > nav a:focus, -body > footer > nav a:active { - color: #494949; -} -body > main { - padding-top: 1rem; - padding-bottom: 1rem; -} -article h1 { - font-size: 1.75rem; -} -article h1 .m-breadcrumb { - color: #666; - font-weight: normal; - font-size: 16px; - padding-top: 8px; - padding-bottom: 8px; -} -article h1 .m-breadcrumb a { - color: #26a9e0; -} -article h1 .m-breadcrumb a:hover, -article h1 a:focus, -article h1 a:active { - color: #26a9e0; -} -article hr { - width: 75%; - border-width: 2px 0 0 0; - border-style: solid; - border-color: #92d050; - margin: auto; -} -article section hr { - width: 50%; - border-width: 1px 0 0 0; - border-style: solid; - border-color: #ddd; - margin: auto; - padding-top: 5px; - padding-bottom: 10px; -} -article > header h1 { - font-size: 2rem; - margin-bottom: 0.5rem; -} -article h1 a, -article > header h1, -article > header h1 a, -article section > h2, -article section > h2 a, -article section > h3, -article section > h3 a, -article section > h4, -article section > h4 a, -article section > h5, -article section > h5 a, -article section > h6, -article section > h6 a { - color: #000000; -} -article h1 a:hover, -article > header h1 a:hover, -article > header h1 a:focus, -article > header h1 a:active, -article section > h2 a:hover, -article section > h2 a:focus, -article section > h2 a:active, -article section > h3 a:hover, -article section > h3 a:focus, -article section > h3 a:active, -article section > h4 a:hover, -article section > h4 a:focus, -article section > h4 a:active, -article section > h5 a:hover, -article section > h5 a:focus, -article section > h5 a:active, -article section > h6 a:hover, -article section > h6 a:focus, -article section > h6 a:active { - color: #000000; -} -article > header .m-date { - display: block; - width: 2.5rem; - float: left; - text-align: center; - line-height: 95%; - font-size: 0.75rem; - font-weight: normal; - white-space: nowrap; - border-right-style: solid; - border-right-width: 0.125rem; - border-color: #000000; - padding-right: 0.75rem; - margin-top: -0.1rem; - margin-right: 0.75rem; - margin-bottom: 0.25rem; -} -article > header .m-date-day { - display: block; - font-weight: bold; - padding-top: 0.2rem; - padding-bottom: 0.15rem; - font-size: 1.25rem; -} -article > header p { - color: #7a7a7a; - font-size: 1.125rem; -} -article > header h1::after { - content: ' '; - clear: both; - display: table; -} -article > footer { - color: #969696; -} -article > footer p { - font-style: italic; - font-size: 0.85rem; - text-indent: 0; -} -article h1 a, -article > header h1 a, -article section > h2 a, -article section > h3 a, -article section > h4 a, -article section > h5 a, -article section > h6 a { - text-decoration: none; -} -#m-landing-image, -#m-cover-image, -article#m-jumbo > header #m-jumbo-image { - background-size: cover; - background-color: #666666; - background-position: center center; - background-repeat: no-repeat; - margin-top: -4rem; - padding-top: 5rem; -} -#m-landing-image { - color: #ffffff; -} -#m-cover-image { - height: 30rem; - margin-bottom: -26rem; -} -#m-landing-cover h1 { - font-size: 2.8rem; - margin-top: -0.5rem; - padding-left: 1.5rem; - padding-bottom: 1rem; - text-transform: capitalize; -} -#m-landing-cover { - padding-bottom: 10rem; - margin-bottom: -6rem; -} -article#m-jumbo { - margin-top: -1rem; -} -#m-landing-cover, -#m-cover-image > div, -article#m-jumbo > header #m-jumbo-cover { - background: linear-gradient( - transparent 0%, - transparent 50%, - #e8e8e8 100% - ); - width: 100%; - height: 100%; -} -article#m-jumbo > header h1, -article#m-jumbo > header h2 { - text-align: center; - font-weight: bold; -} -article#m-jumbo > header a { - text-decoration: none; -} -article#m-jumbo > header #m-jumbo-cover { - padding-bottom: 5rem; -} -article#m-jumbo > header #m-jumbo-image { - font-size: 2.5vmin; - margin-bottom: -3rem; -} -article#m-jumbo > header h1 { - font-size: 10vmin; -} -article#m-jumbo > header h2 { - font-size: 3vmin; -} -@media screen and (max-height: 640px), screen and (max-width: 640px) { - article#m-jumbo > header h1 { - font-size: 3rem; - } - article#m-jumbo > header #m-jumbo-image, - article#m-jumbo > header h2 { - font-size: 1rem; - } -} -article#m-jumbo > header, -article#m-jumbo > header h1, -article#m-jumbo > header a { - color: #ffffff; -} -article#m-jumbo > header a:hover, -article#m-jumbo > header a:focus, -article#m-jumbo > header a:active { - color: #f0f0f0; -} -article#m-jumbo.m-inverted > header, -article#m-jumbo.m-inverted > header h1, -article#m-jumbo.m-inverted > header a { - color: #000000; -} -article#m-jumbo.m-inverted > header a:hover, -article#m-jumbo.m-inverted > header a:focus, -article#m-jumbo.m-inverted > header a:active { - color: #0f0f0f; -} -.m-landing-news h3 a { - color: #000000; - text-decoration: none; - text-transform: capitalize; -} -.m-landing-news h3 a:hover, -.m-landing-news h3 a:hover, -.m-landing-news h3 a:focus, -.m-landing-news h3 a:active { - color: #000000; -} -.m-landing-news time { - display: inline-block; - margin-left: 1rem; - float: right; -} -.m-article-pagination { - text-align: center; - padding: 1rem; -} -nav.m-navpanel { - text-align: center; -} -nav.m-navpanel h3 { - text-transform: capitalize; - font-weight: normal; -} -nav.m-navpanel ol { - text-transform: capitalize; -} -nav.m-navpanel ol, -nav.m-navpanel ul { - list-style-type: none; - padding: 0; -} -nav.m-navpanel a { - color: #292929; - text-decoration: none; -} -nav.m-navpanel a:hover, -nav.m-navpanel a:focus, -nav.m-navpanel a:active { - color: #cb4b16; -} -ul.m-tagcloud li { - display: inline; -} -ul.m-tagcloud li.m-tag-1 { - font-size: 0.75rem; -} -ul.m-tagcloud li.m-tag-2 { - font-size: 0.825rem; -} -ul.m-tagcloud li.m-tag-3 { - font-size: 1rem; -} -ul.m-tagcloud li.m-tag-4 { - font-size: 1.25rem; -} -ul.m-tagcloud li.m-tag-5 { - font-size: 1.5rem; -} -article section:target figure.m-code-figure, -article section:target figure.m-console-figure { - z-index: 1; -} -article, -article > header, -article section { - margin-bottom: 1rem; -} -article:last-child, -article section:last-child { - margin-bottom: 0; -} -.m-container-inflatable section:target > .m-note, -.m-container-inflatable section:target > .m-frame, -.m-container-inflatable section:target > .m-block, -.m-container-inflatable section:target > pre, -.m-container-inflatable section:target > .m-code-figure > pre:first-child, -.m-container-inflatable section:target > .m-console-figure > pre:first-child, -.m-container-inflatable section:target section > .m-note, -.m-container-inflatable section:target section > .m-frame, -.m-container-inflatable section:target section > .m-block, -.m-container-inflatable section:target section > pre, -.m-container-inflatable section:target section > .m-code-figure > pre:first-child, -.m-container-inflatable section:target section > .m-console-figure > pre:first-child, -.m-container-inflatable section:target [class*='m-center-'] > .m-note, -.m-container-inflatable section:target [class*='m-center-'] > .m-frame, -.m-container-inflatable section:target [class*='m-center-'] > .m-block, -.m-container-inflatable section:target [class*='m-center-'] > pre, -.m-container-inflatable - section:target - [class*='m-center-'] - > .m-code-figure - > pre:first-child, -.m-container-inflatable - section:target - [class*='m-center-'] - > .m-console-figure - > pre:first-child, -.m-container-inflatable section:target [class*='m-left-'] > .m-note, -.m-container-inflatable section:target [class*='m-left-'] > .m-frame, -.m-container-inflatable section:target [class*='m-left-'] > .m-block, -.m-container-inflatable section:target [class*='m-left-'] > pre, -.m-container-inflatable - section:target - [class*='m-left-'] - > .m-code-figure - > pre:first-child, -.m-container-inflatable - section:target - [class*='m-left-'] - > .m-console-figure - > pre:first-child, -.m-container-inflatable section:target [class*='m-right-'] > .m-note, -.m-container-inflatable section:target [class*='m-right-'] > .m-frame, -.m-container-inflatable section:target [class*='m-right-'] > .m-block, -.m-container-inflatable section:target [class*='m-right-'] > pre, -.m-container-inflatable - section:target - [class*='m-right-'] - > .m-code-figure - > pre:first-child, -.m-container-inflatable - section:target - [class*='m-right-'] - > .m-console-figure - > pre:first-child, -.m-container-inflatable section:target .m-container-inflate > .m-note, -.m-container-inflatable section:target .m-container-inflate > .m-frame, -.m-container-inflatable section:target .m-container-inflate > .m-block, -.m-container-inflatable section:target .m-container-inflate > pre, -.m-container-inflatable - section:target - .m-container-inflate - > .m-code-figure - > pre:first-child, -.m-container-inflatable - section:target - .m-container-inflate - > .m-console-figure - > pre:first-child { - margin-left: -1rem; - border-left-style: solid; - border-left-width: 0.25rem; - border-top-left-radius: 0; - border-bottom-left-radius: 0; - padding-left: 0.75rem; -} -.m-container-inflatable section:target > .m-code-figure::before, -.m-container-inflatable section:target > .m-console-figure::before, -.m-container-inflatable section:target section > .m-code-figure::before, -.m-container-inflatable section:target section > .m-console-figure::before, -.m-container-inflatable section:target [class*='m-center-'] > .m-code-figure::before, -.m-container-inflatable section:target [class*='m-center-'] > .m-console-figure::before, -.m-container-inflatable section:target [class*='m-left-'] > .m-code-figure::before, -.m-container-inflatable section:target [class*='m-left-'] > .m-console-figure::before, -.m-container-inflatable section:target [class*='m-right-'] > .m-code-figure::before, -.m-container-inflatable section:target [class*='m-right-'] > .m-console-figure::before, -.m-container-inflatable section:target .m-container-inflate > .m-code-figure::before, -.m-container-inflatable - section:target - .m-container-inflate - > .m-console-figure::before { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - border-left-width: 0.25rem; -} -.m-container-inflatable section:target > .m-code-figure > pre.m-nopad, -.m-container-inflatable section:target > .m-console-figure > pre.m-nopad { - margin-left: -0.75rem; - padding-left: -0.75rem; -} -@media screen and (min-width: 576px) { - .m-container-inflatable section:target .m-center-s > .m-note, - .m-container-inflatable section:target .m-center-s > pre, - .m-container-inflatable - section:target - .m-center-s - > figure.m-code-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-center-s - > figure.m-console-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-right-s - > figure.m-code-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-right-s - > figure.m-console-figure - > pre:first-child { - border-left-width: 0; - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - padding-left: 1rem; - } - .m-container-inflatable section:target .m-center-s > .m-block, - .m-container-inflatable section:target .m-right-s > .m-block { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - } - .m-container-inflatable section:target .m-center-s > .m-frame, - .m-container-inflatable section:target .m-right-s > .m-frame { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - border-left-width: 0.125rem; - padding-left: 0.875rem; - } - .m-container-inflatable section:target .m-right-s > .m-block, - .m-container-inflatable section:target .m-right-s > .m-frame { - margin-left: 0; - } - .m-container-inflatable section:target .m-right-s > .m-note, - .m-container-inflatable section:target .m-right-s > pre { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - margin-left: 0; - border-left-width: 0; - padding-left: 1rem; - } - .m-container-inflatable section:target .m-center-s > figure.m-code-figure::before, - .m-container-inflatable section:target .m-center-s > figure.m-console-figure::before, - .m-container-inflatable section:target .m-right-s > figure.m-code-figure::before, - .m-container-inflatable section:target .m-right-s > figure.m-console-figure::before { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - border-left-width: 0.125rem; - } -} -@media screen and (min-width: 768px) { - .m-container-inflatable section:target .m-center-m > .m-note, - .m-container-inflatable section:target .m-center-m > pre, - .m-container-inflatable - section:target - .m-center-m - > figure.m-code-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-center-m - > figure.m-console-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-right-m - > figure.m-code-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-right-m - > figure.m-console-figure - > pre:first-child { - border-left-width: 0; - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - padding-left: 1rem; - } - .m-container-inflatable section:target .m-center-m > .m-block, - .m-container-inflatable section:target .m-right-m > .m-block { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - } - .m-container-inflatable section:target .m-center-m > .m-frame, - .m-container-inflatable section:target .m-right-m > .m-frame { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - border-left-width: 0.125rem; - padding-left: 0.875rem; - } - .m-container-inflatable section:target .m-right-m > .m-block, - .m-container-inflatable section:target .m-right-m > .m-frame { - margin-left: 0; - } - .m-container-inflatable section:target .m-right-m > .m-note, - .m-container-inflatable section:target .m-right-m > pre { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - margin-left: 0; - border-left-width: 0; - padding-left: 1rem; - } - .m-container-inflatable section:target .m-center-m > figure.m-code-figure::before, - .m-container-inflatable section:target .m-center-m > figure.m-console-figure::before, - .m-container-inflatable section:target .m-right-m > figure.m-code-figure::before, - .m-container-inflatable section:target .m-right-m > figure.m-console-figure::before { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - border-left-width: 0.125rem; - } -} -@media screen and (min-width: 992px) { - .m-container-inflatable section:target .m-center-l > .m-note, - .m-container-inflatable section:target .m-center-l > pre, - .m-container-inflatable - section:target - .m-center-l - > figure.m-code-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-center-l - > figure.m-console-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-right-l - > figure.m-code-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-right-l - > figure.m-console-figure - > pre:first-child { - border-left-width: 0; - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - padding-left: 1rem; - } - .m-container-inflatable section:target .m-center-l > .m-block, - .m-container-inflatable section:target .m-right-l > .m-block { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - } - .m-container-inflatable section:target .m-center-l > .m-frame, - .m-container-inflatable section:target .m-right-l > .m-frame { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - border-left-width: 0.125rem; - padding-left: 0.875rem; - } - .m-container-inflatable section:target .m-right-l > .m-block, - .m-container-inflatable section:target .m-right-l > .m-frame { - margin-left: 0; - } - .m-container-inflatable section:target .m-right-l > .m-note, - .m-container-inflatable section:target .m-right-l > pre { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - margin-left: 0; - border-left-width: 0; - padding-left: 1rem; - } - .m-container-inflatable section:target .m-center-l > figure.m-code-figure::before, - .m-container-inflatable section:target .m-center-l > figure.m-console-figure::before, - .m-container-inflatable section:target .m-right-l > figure.m-code-figure::before, - .m-container-inflatable section:target .m-right-l > figure.m-console-figure::before { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - border-left-width: 0.125rem; - } -} -.m-container-inflatable section:target > figure.m-code-figure::before, -.m-container-inflatable section:target > figure.m-console-figure::before, -.m-container-inflatable section:target section > figure.m-code-figure::before, -.m-container-inflatable section:target section > figure.m-console-figure::before, -.m-container-inflatable - section:target - [class*='m-center-'] - > figure.m-code-figure::before, -.m-container-inflatable - section:target - [class*='m-center-'] - > figure.m-console-figure::before, -.m-container-inflatable - section:target - [class*='m-left-'] - > figure.m-code-figure::before, -.m-container-inflatable - section:target - [class*='m-left-'] - > figure.m-console-figure::before, -.m-container-inflatable - section:target - [class*='m-right-'] - > figure.m-code-figure::before, -.m-container-inflatable - section:target - [class*='m-right-'] - > figure.m-console-figure::before, -.m-container-inflatable - section:target - .m-container-inflatable - > figure.m-code-figure::before, -.m-container-inflatable - section:target - .m-container-inflatable - > figure.m-console-figure::before { - border-left-color: #ddd; -} -@media screen and (min-width: 576px) { - .m-container-inflatable section:target .m-center-s > figure.m-code-figure::before, - .m-container-inflatable section:target .m-right-s > figure.m-code-figure::before { - border-color: #f7f7f7; - } - .m-container-inflatable section:target .m-center-s > figure.m-console-figure::before, - .m-container-inflatable section:target .m-right-s > figure.m-console-figure::before { - border-color: #f7f7f7; - } -} -@media screen and (min-width: 768px) { - .m-container-inflatable section:target .m-center-m > figure.m-code-figure::before, - .m-container-inflatable section:target .m-right-m > figure.m-code-figure::before { - border-color: #f7f7f7; - } - .m-container-inflatable section:target .m-center-m > figure.m-console-figure::before, - .m-container-inflatable section:target .m-right-m > figure.m-console-figure::before { - border-color: #f7f7f7; - } -} -@media screen and (min-width: 992px) { - .m-container-inflatable section:target .m-center-l > figure.m-code-figure::before, - .m-container-inflatable section:target .m-right-l > figure.m-code-figure::before { - border-color: #f7f7f7; - } - .m-container-inflatable section:target .m-center-l > figure.m-console-figure::before, - .m-container-inflatable section:target .m-right-l > figure.m-console-figure::before { - border-color: #f7f7f7; - } -} -.m-container-inflatable section:target pre, -.m-container-inflatable section:target figure.m-code-figure > pre:first-child, -.m-container-inflatable section:target figure.m-console-figure > pre:first-child { - border-color: #ddd; -} -.m-container-inflatable section:target .m-note.m-default { - border-color: #ddd; -} -.m-container-inflatable section:target .m-note.m-primary { - border-color: #31708f; -} -.m-container-inflatable section:target .m-note.m-success { - border-color: #9ad36a; -} -.m-container-inflatable section:target .m-note.m-warning { - border-color: #f9cf79; -} -.m-container-inflatable section:target .m-note.m-danger { - border-color: #f60000; -} -.m-container-inflatable section:target .m-note.m-info { - border-color: #31708f; -} -.m-container-inflatable section:target .m-note.m-dim { - border-color: #666; -} - -.m-code .c { - color: #95a5a6; -} -.m-code .err { - color: #a61717; -} -.m-code .k { - color: #728e00; -} -.m-code .n { - color: #434f54; -} -.m-code .o { - color: #728e00; -} -.m-code .ch { - color: #95a5a6; -} -.m-code .cm { - color: #95a5a6; -} -.m-code .cp { - color: #728e00; -} -.m-code .cpf { - color: #95a5a6; -} -.m-code .c1 { - color: #95a5a6; -} -.m-code .cs { - color: #95a5a6; -} -.m-code .kc { - color: #00979d; -} -.m-code .kd { - color: #728e00; -} -.m-code .kn { - color: #728e00; -} -.m-code .kp { - color: #00979d; -} -.m-code .kr { - color: #00979d; -} -.m-code .kt { - color: #00979d; -} -.m-code .m { - color: #8a7b52; -} -.m-code .s { - color: #7f8c8d; -} -.m-code .na { - color: #434f54; -} -.m-code .nb { - color: #728e00; -} -.m-code .nc { - color: #434f54; -} -.m-code .no { - color: #434f54; -} -.m-code .nd { - color: #434f54; -} -.m-code .ni { - color: #434f54; -} -.m-code .ne { - color: #434f54; -} -.m-code .nf { - color: #d35400; -} -.m-code .nl { - color: #434f54; -} -.m-code .nn { - color: #434f54; -} -.m-code .nx { - color: #728e00; -} -.m-code .py { - color: #434f54; -} -.m-code .nt { - color: #434f54; -} -.m-code .nv { - color: #434f54; -} -.m-code .ow { - color: #728e00; -} -.m-code .mb { - color: #8a7b52; -} -.m-code .mf { - color: #8a7b52; -} -.m-code .mh { - color: #8a7b52; -} -.m-code .mi { - color: #8a7b52; -} -.m-code .mo { - color: #8a7b52; -} -.m-code .sa { - color: #7f8c8d; -} -.m-code .sb { - color: #7f8c8d; -} -.m-code .sc { - color: #7f8c8d; -} -.m-code .dl { - color: #7f8c8d; -} -.m-code .sd { - color: #7f8c8d; -} -.m-code .s2 { - color: #7f8c8d; -} -.m-code .se { - color: #7f8c8d; -} -.m-code .sh { - color: #7f8c8d; -} -.m-code .si { - color: #7f8c8d; -} -.m-code .sx { - color: #7f8c8d; -} -.m-code .sr { - color: #7f8c8d; -} -.m-code .s1 { - color: #7f8c8d; -} -.m-code .ss { - color: #7f8c8d; -} -.m-code .bp { - color: #728e00; -} -.m-code .fm { - color: #d35400; -} -.m-code .vc { - color: #434f54; -} -.m-code .vg { - color: #434f54; -} -.m-code .vi { - color: #434f54; -} -.m-code .vm { - color: #434f54; -} -.m-code .il { - color: #8a7b52; -} - -.m-console .hll { - background-color: #ffffcc; -} -.m-console .g-AnsiBackgroundBlack { - background-color: #232627; -} -.m-console .g-AnsiBackgroundBlue { - background-color: #1d99f3; -} -.m-console .g-AnsiBackgroundBrightBlack { - background-color: #7f8c8d; -} -.m-console .g-AnsiBackgroundBrightBlue { - background-color: #3daee9; -} -.m-console .g-AnsiBackgroundBrightCyan { - background-color: #16a085; -} -.m-console .g-AnsiBackgroundBrightGreen { - background-color: #1cdc9a; -} -.m-console .g-AnsiBackgroundBrightMagenta { - background-color: #8e44ad; -} -.m-console .g-AnsiBackgroundBrightRed { - background-color: #c0392b; -} -.m-console .g-AnsiBackgroundBrightWhite { - background-color: #ffffff; -} -.m-console .g-AnsiBackgroundBrightYellow { - background-color: #fdbc4b; -} -.m-console .g-AnsiBackgroundCyan { - background-color: #1abc9c; -} -.m-console .g-AnsiBackgroundDefault { - background-color: #fcfcfc; -} -.m-console .g-AnsiBackgroundGreen { - background-color: #11d116; -} -.m-console .g-AnsiBackgroundMagenta { - background-color: #9b59b6; -} -.m-console .g-AnsiBackgroundRed { - background-color: #ed1515; -} -.m-console .g-AnsiBackgroundWhite { - background-color: #fcfcfc; -} -.m-console .g-AnsiBackgroundYellow { - background-color: #f67400; -} -.m-console .g-AnsiBlack { - color: #232627; -} -.m-console .g-AnsiBlue { - color: #1d99f3; -} -.m-console .g-AnsiBrightBlack { - color: #7f8c8d; - font-weight: bold; -} -.m-console .g-AnsiBrightBlue { - color: #3daee9; - font-weight: bold; -} -.m-console .g-AnsiBrightCyan { - color: #16a085; - font-weight: bold; -} -.m-console .g-AnsiBrightDefault { - color: #ffffff; - font-weight: bold; -} -.m-console .g-AnsiBrightGreen { - color: #1cdc9a; - font-weight: bold; -} -.m-console .g-AnsiBrightInvertedDefault { - color: #1a1c1d; - font-weight: bold; -} -.m-console .g-AnsiBrightMagenta { - color: #8e44ad; - font-weight: bold; -} -.m-console .g-AnsiBrightRed { - color: #c0392b; - font-weight: bold; -} -.m-console .g-AnsiBrightWhite { - color: #ffffff; - font-weight: bold; -} -.m-console .g-AnsiBrightYellow { - color: #fdbc4b; - font-weight: bold; -} -.m-console .g-AnsiCyan { - color: #1abc9c; -} -.m-console .g-AnsiDefault { - color: #fcfcfc; -} -.m-console .g-AnsiGreen { - color: #11d116; -} -.m-console .g-AnsiInvertedDefault { - color: #1a1c1d; -} -.m-console .g-AnsiMagenta { - color: #9b59b6; -} -.m-console .g-AnsiRed { - color: #ed1515; -} -.m-console .g-AnsiWhite { - color: #fcfcfc; -} -.m-console .g-AnsiYellow { - color: #f67400; -} -.m-console .go { - color: #fcfcfc; -} -.m-console .gp { - color: #16a085; - font-weight: bold; -} -.m-console .w { - color: #fcfcfc; -} - -a.m-doc, -a.m-doc-self, -a.m-doc-external, -ul.m-doc li.m-doc-expansible > a:first-child, -ul.m-doc li.m-doc-collapsible > a:first-child, -.m-code.m-inverted.m-doc-include > a { - text-decoration: none; -} -a.m-doc, -a.m-doc-self { - font-weight: bold; -} -.m-thin a.m-doc, -.m-thin a.m-doc-self { - font-weight: normal; -} -ul.m-doc li.m-doc-expansible > a:first-child, -ul.m-doc li.m-doc-collapsible > a:first-child, -ul.m-doc li.m-doc-expansible > a:first-child:hover, -ul.m-doc li.m-doc-expansible > a:first-child:focus, -ul.m-doc li.m-doc-expansible > a:first-child:active, -ul.m-doc li.m-doc-collapsible > a:first-child:hover, -ul.m-doc li.m-doc-collapsible > a:first-child:focus, -ul.m-doc li.m-doc-collapsible > a:first-child:active { - color: #000000; -} -a.m-doc-self, -ul.m-doc li.m-doc-expansible > a:first-child::before, -ul.m-doc li.m-doc-collapsible > a:first-child::before { - color: #26a9e0; -} -a.m-doc-self:hover, -a.m-doc-self:focus, -a.m-doc-self:active, -ul.m-doc li.m-doc-expansible > a:first-child:hover::before, -ul.m-doc li.m-doc-expansible > a:first-child:focus::before, -ul.m-doc li.m-doc-expansible > a:first-child:active::before, -ul.m-doc li.m-doc-collapsible > a:first-child:hover::before, -ul.m-doc li.m-doc-collapsible > a:first-child:focus::before, -ul.m-doc li.m-doc-collapsible > a:first-child:active::before { - color: #26a9e0; -} -h3 a.m-doc-external { - font-weight: normal; -} -span.m-doc-wrap-bumper { - margin-right: -1rem; - display: inline-block; - vertical-align: text-top; -} -span.m-doc-wrap { - padding-left: 1rem; - display: inline-block; - vertical-align: text-top; - white-space: pre-line; - max-width: 100%; -} -dl.m-doc dd { - margin-bottom: 0.5rem; -} -dl.m-doc dd { - margin-left: 0; - padding-left: 2.5rem; -} -ul.m-doc { - list-style: none; - margin-left: 1.0375rem; - padding-left: 0.9rem; - border-left-color: #ddd; - border-left-width: 0.0625rem; - border-left-style: solid; -} -ul.m-doc li { - text-indent: -1rem; - padding-left: 1rem; -} -ul.m-doc li.m-doc-expansible > ul { - display: none; -} -ul.m-doc li.m-doc-expansible, -ul.m-doc li.m-doc-collapsible { - padding-left: 0.6rem; -} -ul.m-doc li.m-doc-expansible > ul.m-doc, -ul.m-doc li.m-doc-collapsible > ul.m-doc { - margin-left: 0.5rem; -} -ul.m-doc li.m-doc-expansible > a:first-child::before, -ul.m-doc li.m-doc-collapsible > a:first-child::before { - background-color: #e8e8e8; - display: inline-block; - width: 0.4rem; - font-weight: bold; -} -ul.m-doc li.m-doc-expansible > a:first-child::before { - content: '+'; -} -ul.m-doc li.m-doc-collapsible > a:first-child::before { - content: '-'; -} -h1 .m-doc-template, -h1 .m-doc-include { - font-size: 1.3rem; - font-weight: normal; - float: right; -} -h1 .m-doc-include:last-child { - margin-bottom: -0.5rem; -} -h3 .m-doc-template, -h3 .m-doc-include { - font-size: 1rem; - font-weight: normal; -} -.m-doc-template, -dl.m-doc dd, -ul.m-doc li > span.m-doc { - color: #666; -} -dl.m-doc dd svg.m-math, -ul.m-doc li > span.m-doc svg.m-math { - fill: #666; -} -.m-doc-template a, -dl.m-doc dd a, -ul.m-doc li > span.m-doc a { - color: #949494; -} -.m-doc-template a:hover, -.m-doc-template a:focus, -.m-doc-template a:active, -dl.m-doc dd a:hover, -dl.m-doc dd a:focus, -dl.m-doc dd a:active, -ul.m-doc li > span.m-doc a:hover, -ul.m-doc li > span.m-doc a:focus, -ul.m-doc li > span.m-doc a:active { - color: #949494; -} -.m-code.m-inverted.m-doc-include > a:link, -.m-code.m-inverted.m-doc-include > a:visited { - opacity: 0.6666; -} -.m-code.m-inverted.m-doc-include > a:hover, -.m-code.m-inverted.m-doc-include > a:focus, -.m-code.m-inverted.m-doc-include > a:active { - opacity: 1; -} -article section.m-doc-details > div { - margin-top: 0; - margin-left: 0; - margin-right: 0; - position: relative; - padding: 1rem; -} -article section.m-doc-details > div::before { - position: absolute; - content: ' '; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: -1; - border-style: solid; - border-width: 0.125rem; - border-radius: 0px; - border-color: #f7f7f7; -} -article section.m-doc-details > div > h3:first-child { - position: relative; - margin: -1rem -1rem 1rem -1rem; - padding: 0.5rem 1rem; - background-color: #ffffff; - border-top-left-radius: 0px; - border-top-right-radius: 0px; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - border-style: solid; - border-width: 2px; - border-color: rgba(91, 91, 91, 0.33); -} -article section.m-doc-details:target { - border-color: transparent; -} -article section.m-doc-details:target > div { - z-index: 1; -} -.m-container-inflatable > .m-row > [class*='m-col-'] section.m-doc-details > div { - margin-left: -1rem; - margin-right: -1rem; -} -#m-search-button { - color: #fff; - margin-left: 30px; - cursor: pointer; - font-size: 18px; - line-height: 1; - padding: 30.5px 0; -} -#m-search-button:before { - font-family: 'FontAwesome'; - content: '\f002'; -} -a.m-doc-search-icon { - padding-left: 1rem; - padding-right: 1rem; -} -a.m-doc-search-icon svg { - fill: #ffffff; -} -body > header > nav #m-navbar-collapse a.m-doc-search-icon svg { - vertical-align: -5%; -} -a.m-doc-search-icon:focus svg, -a.m-doc-search-icon:hover svg, -a.m-doc-search-icon:active svg { - fill: #ffffff; -} -.m-doc-search { - display: none; - z-index: 10; - position: fixed; - left: 0; - right: 0; - top: 110px; - bottom: 0; - background-color: #e8e8e8; -} -.m-doc-search:target { - display: block; -} -.m-doc-search > a { - display: block; - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; -} -.m-doc-search-header { - margin-top: 2.5rem; - padding: 0.5rem 1rem; - height: 2rem; -} -.m-doc-search-header > div:first-child { - float: right; -} -.m-doc-search-content { - background-color: #ffffff; - border-radius: 0px; - padding: 1rem; -} -.m-doc-search input { - width: 100%; - height: 3rem; - font-size: 1.2rem; - border-width: 0; - color: #000000; - background-color: #e8e8e8; - border-radius: 0px; - margin-bottom: 1rem; - padding: 0 1rem; -} -.m-doc-search #search-notfound { - display: none; -} -.m-doc-search ul#search-results { - list-style-type: none; - padding-left: 0; - max-height: calc(100vh - 12.5rem); - overflow-y: auto; - display: none; -} -.m-doc-search ul#search-results li a { - display: block; - padding-left: 1rem; - padding-right: 1rem; - text-decoration: none; - width: 100%; - line-height: 1.5rem; - color: #000000; -} -.m-doc-search ul#search-results li a > div { - white-space: nowrap; - overflow: hidden; -} -.m-doc-search ul#search-results li a > div:not(.m-doc-search-alias) { - direction: rtl; -} -.m-doc-search ul#search-results li a .m-label { - float: right; - line-height: 1rem; - margin-top: 0.1rem; - margin-left: 0.25rem; -} -.m-doc-search ul#search-results li a .m-label.m-flat { - margin-right: -0.75rem; -} -.m-doc-search ul#search-results li#search-current a { - background-color: transparent; -} -.m-doc-search ul#search-results li#search-current.m-doc-search-copied a { - background-color: transparent; -} -.m-doc-search-typed { - color: #26a9e0; -} -.m-doc-search input[type='search'] { - -webkit-appearance: textfield; -} -.m-doc-search input[type='search']::-webkit-search-decoration, -.m-doc-search input[type='search']::-webkit-search-cancel-button, -.m-doc-search input[type='search']::-webkit-search-results-button, -.m-doc-search input[type='search']::-webkit-search-results-decoration { - display: none; -} From 1f9293240d516a16165467dc4374460d71256646 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 14 Jun 2024 13:01:48 -0400 Subject: [PATCH 082/138] Document extras, dirs, CI Signed-off-by: Sara Damiano --- continuous_integration/ReadMe.md | 27 ++++++++ docs/Doxyfile | 3 +- docs/directories.dox | 25 +++++++ docs/doxygen_extra_pages.dox | 2 +- docs/mcss-conf.py | 66 +++++++++++++++---- .../LTExBee_FirstConnection.ino | 6 ++ .../LTExBee_FirstConnectionBypass.ino | 6 ++ extras/ReadMe.md | 26 ++++++++ extras/Stream_Debug/Stream_Debug.ino | 6 ++ extras/extras.dox | 44 +++++++++++++ extras/i2c_scanner/i2c_scanner.ino | 57 ++++++++-------- extras/i2c_warmUp/i2c_warmUp.ino | 6 ++ .../interrupt_counter/interrupt_counter.ino | 5 ++ extras/mega_serial_spy/mega_serial_spy.ino | 6 ++ extras/oneWireSearch/oneWireSearch.ino | 33 +++++----- extras/powerOn/powerOn.ino | 6 ++ extras/resetBee/resetBee.ino | 5 ++ .../sdi12_address_change.ino | 61 ++++------------- 18 files changed, 282 insertions(+), 108 deletions(-) create mode 100644 continuous_integration/ReadMe.md create mode 100644 docs/directories.dox create mode 100644 extras/ReadMe.md create mode 100644 extras/extras.dox diff --git a/continuous_integration/ReadMe.md b/continuous_integration/ReadMe.md new file mode 100644 index 000000000..700c66d49 --- /dev/null +++ b/continuous_integration/ReadMe.md @@ -0,0 +1,27 @@ +# Extra scripts for Continuous Integration Using GitHub Actions + +- check_component_inclusion.py + - A python script to check that all sensor, modem, and publisher classes are included in the massive menu a la carte example. + +- dependencies.json + - A copy of the library dependencies in library.json to diff against for dependency changes. + - The dependencies.json is automatically generated by a git pre-commit hook. + +- pre-commit-check-deps.py + - A python script to copy from the library.json to dependencies.json for rebuilding dependency archives on the GitHub actions runner. + - This is run as a pre-commit hook + +- generate_job_matrix.py + - A python script to generate a series of shell scripts to splice apart the menu a la carte example and run each sensor, modem, and publisher as indivudual testing jobs on a number of different processors. + +- install-deps-arsuino-cli.sh + - A shell script to install all Arduino library dependencies on the GitHub actions runner used for CI testing. + +- install-deps-platformio.sh + - A shell script to install all PlatformIO library dependencies on the GitHub actions runner used for CI testing. + +- continuous_integration/platformio.ini + - PlatformIO environments for CI testing + +- continuous_integration/platformio_extra_flags.ini + - Even more PlatformIO environments for CI testing diff --git a/docs/Doxyfile b/docs/Doxyfile index 2e9a286dc..83408dc31 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1043,7 +1043,8 @@ EXCLUDE = ../src/ReadMe.md \ ../examples/logger_test \ ../examples/logger_test_nonew \ ../examples/YosemitechDO \ - ../src/sensors/table.md + ../src/sensors/table.md \ + ../continuous_integration_artifacts # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded diff --git a/docs/directories.dox b/docs/directories.dox new file mode 100644 index 000000000..21f12bbbe --- /dev/null +++ b/docs/directories.dox @@ -0,0 +1,25 @@ +/** + * @dir docs + * + * @brief Contains extra documentation and files to help build the documentation + */ +/** + * @dir docs/FAQ + * + * @brief Contains documentation on frequently asked questions + */ +/** + * @dir docs/Getting-Started + * + * @brief Contains documentation for new users + */ +/** + * @dir examples + * + * @brief Contains all of the example sketches + */ +/** + * @dir extras + * + * @brief Contains extra sketches for testing sensors and sub-libraries + */ diff --git a/docs/doxygen_extra_pages.dox b/docs/doxygen_extra_pages.dox index 22c3817dd..e51526828 100644 --- a/docs/doxygen_extra_pages.dox +++ b/docs/doxygen_extra_pages.dox @@ -26,4 +26,4 @@ Here are links to detailed information about the various supported sensors and m @subpage page_sensor_notes @subpage page_modem_notes -*/ \ No newline at end of file +*/ diff --git a/docs/mcss-conf.py b/docs/mcss-conf.py index 990cb59a5..afad978a8 100644 --- a/docs/mcss-conf.py +++ b/docs/mcss-conf.py @@ -45,31 +45,66 @@ # ), # ], ), - ("Library Dependencies", "page_library_dependencies",), - ("Physical Dependencies", "page_physical_dependencies",), - ("Terminology", "page_library_terminology",), - ("Other Sensor and Modem Notes", "page_other_notes",), + ( + "Library Dependencies", + "page_library_dependencies", + ), + ( + "Physical Dependencies", + "page_physical_dependencies", + ), + ( + "Terminology", + "page_library_terminology", + ), + ( + "Other Sensor and Modem Notes", + "page_other_notes", + ), ], ), ( "FAQs", "page_faq", [ - ("Processor Compatibility", "page_processor_compatibility",), - ("Arduino Streams and Software Serial", "page_arduino_streams",), - ("Power Draw over Data Lines", "page_power_parasites",), + ( + "Processor Compatibility", + "page_processor_compatibility", + ), + ( + "Arduino Streams and Software Serial", + "page_arduino_streams", + ), + ( + "Power Draw over Data Lines", + "page_power_parasites", + ), ("Decreasing Memory Footprint", "page_memory_use"), - ("In-Library Debugging", "page_code_debugging",), - ("For Developers", "page_for_developers",), + ( + "In-Library Debugging", + "page_code_debugging", + ), + ( + "For Developers", + "page_for_developers", + ), ], ), ("Modules", "modules", []), - ("Classes", "annotated", [],), - ("Source Files", "files", [],), + ( + "Classes", + "annotated", + [], + ), + ( + "Source Files", + "files", + [], + ), ( "Examples", "page_the_examples", - [], + [("Other Helper Sketches", "page_extra_helper_sketches")], # [ # ( # "Basic Functionality", @@ -115,7 +150,11 @@ # ), # ], ), - ("More", "pages", [],), + ( + "More", + "pages", + [], + ), ] LINKS_NAVBAR2 = [] VERSION_LABELS = True @@ -124,6 +163,7 @@ STYLESHEETS = [ "css/m-EnviroDIY+documentation.compiled.css", ] + EXTRA_FILES = ["gp-desktop-logo.png", "gp-mobile-logo.png", "gp-scrolling-logo.png"] DESKTOP_LOGO = "gp-desktop-logo.png" MOBILE_LOGO = "gp-mobile-logo.png" diff --git a/extras/LTExBee_FirstConnection/LTExBee_FirstConnection.ino b/extras/LTExBee_FirstConnection/LTExBee_FirstConnection.ino index 53c5ccefc..cad9ac134 100644 --- a/extras/LTExBee_FirstConnection/LTExBee_FirstConnection.ino +++ b/extras/LTExBee_FirstConnection/LTExBee_FirstConnection.ino @@ -1,3 +1,9 @@ +/** ========================================================================= + * @file LTExBee_FirstConnection.ino + * @brief Testing sketch to set up a never-previously-connected LTE XBee running + * in standard (transparent) mode. + * ======================================================================= */ + #define TINY_GSM_MODEM_XBEE #define TINY_GSM_RX_BUFFER 64 #define TINY_GSM_YIELD_MS 2 diff --git a/extras/LTExBee_FirstConnectionBypass/LTExBee_FirstConnectionBypass.ino b/extras/LTExBee_FirstConnectionBypass/LTExBee_FirstConnectionBypass.ino index 3a53f8de3..7d8b3e7f4 100644 --- a/extras/LTExBee_FirstConnectionBypass/LTExBee_FirstConnectionBypass.ino +++ b/extras/LTExBee_FirstConnectionBypass/LTExBee_FirstConnectionBypass.ino @@ -1,3 +1,9 @@ +/** ========================================================================= + * @file LTExBee_FirstConnectionBypass.ino + * @brief Testing sketch to set up a never-previously-connected LTE XBee running + * in bypass mode. + * ======================================================================= */ + #define TINY_GSM_MODEM_SARAR4 #define TINY_GSM_RX_BUFFER 64 #define TINY_GSM_YIELD_MS 2 diff --git a/extras/ReadMe.md b/extras/ReadMe.md new file mode 100644 index 000000000..c2c2edf53 --- /dev/null +++ b/extras/ReadMe.md @@ -0,0 +1,26 @@ +# Extra Helper Sketches + +A collection of helper sketches to test individual sensor timing and configurations. + +- powerOn.ino + - Testing sketch that simply turns on power to the sensors on the Mayfly. +- oneWireSearch.ino + - Testing sketch to scan for 1-Wire devices + code snippet generator +- i2c_scanner.ino + - Testing sketch to scan for attached I2C devices +- i2c_warmUp.ino + - Testing sketch to see how long an attached I2C device takes to begin to respond to commands. +- interrupt_counter.ino + - Testing sketch counting pin change interrupts. +- resetBee.ino + - Testing sketch to fully reset an XBee +- LTExBee_FirstConnection.ino + - Testing sketch to set up a never-previously-connected LTE XBee running in standard (transparent) mode. +- LTExBee_FirstConnectionBypass.ino + - Testing sketch to set up a never-previously-connected LTE XBee running in bypass mode. +- mega_serial_spy.ino + - Testing sketch to run on an Arduino Mega to print all output from connected serial ports to the terminal. +- sdi12_address_change.ino + - Copy of SDI-12 Example B: Changing the Address of your SDI-12 sensor +- Stream_Debug.ino + - Testing sketch to run StreamDebugger to copy text from one serial output to another. diff --git a/extras/Stream_Debug/Stream_Debug.ino b/extras/Stream_Debug/Stream_Debug.ino index af86151e1..9c2700a82 100644 --- a/extras/Stream_Debug/Stream_Debug.ino +++ b/extras/Stream_Debug/Stream_Debug.ino @@ -1,3 +1,9 @@ +/** ========================================================================= + * @file Stream_Debug.ino + * @brief Testing sketch to run StreamDebugger to copy text from one serial + * output to another. + * ======================================================================= */ + #include #include StreamDebugger StreamDbg(Serial1, Serial); diff --git a/extras/extras.dox b/extras/extras.dox new file mode 100644 index 000000000..5f2184672 --- /dev/null +++ b/extras/extras.dox @@ -0,0 +1,44 @@ +/** + * @example{lineno} powerOn.ino + * @brief Testing sketch that simply turns on power to the sensors on the Mayfly. + */ +/** + * @example{lineno} oneWireSearch.ino + * @brief Testing sketch to scan for 1-Wire devices + code snippet generator + */ +/** + * @example{lineno} i2c_scanner.ino + * @brief Testing sketch to scan for attached I2C devices + */ +/** + * @example{lineno} i2c_warmUp.ino + * @brief Testing sketch to see how long an attached I2C device takes to begin to respond to commands. + */ +/** + * @example{lineno} interrupt_counter.ino + * @brief Testing sketch counting pin change interrupts. + */ +/** + * @example{lineno} resetBee.ino + * @brief Testing sketch to fully reset an XBee + */ +/** + * @example{lineno} LTExBee_FirstConnection.ino + * @brief Testing sketch to set up a never-previously-connected LTE XBee running in standard (transparent) mode. + */ +/** + * @example{lineno} LTExBee_FirstConnectionBypass.ino + * @brief Testing sketch to set up a never-previously-connected LTE XBee running in bypass mode. + */ +/** + * @example{lineno} mega_serial_spy.ino + * @brief Testing sketch to run on an Arduino Mega to print all output from connected serial ports to the terminal. + */ +/** + * @example{lineno} sdi12_address_change.ino + * @brief Copy of SDI-12 Example B: Changing the Address of your SDI-12 Sensor + */ +/** + * @example{lineno} Stream_Debug.ino + * @brief Testing sketch to run StreamDebugger to copy text from one serial output to another. + */ diff --git a/extras/i2c_scanner/i2c_scanner.ino b/extras/i2c_scanner/i2c_scanner.ino index 83ccfa699..21ebc2ba8 100644 --- a/extras/i2c_scanner/i2c_scanner.ino +++ b/extras/i2c_scanner/i2c_scanner.ino @@ -1,31 +1,32 @@ -// -------------------------------------- -// i2c_scanner -// -// Version 1 -// This program (or code that looks like it) -// can be found in many places. -// For example on the Arduino.cc forum. -// The original author is not know. -// Version 2, Juni 2012, Using Arduino 1.0.1 -// Adapted to be as simple as possible by Arduino.cc user Krodal -// Version 3, Feb 26 2013 -// V3 by louarnold -// Version 4, March 3, 2013, Using Arduino 1.0.3 -// by Arduino.cc user Krodal. -// Changes by louarnold removed. -// Scanning addresses changed from 0...127 to 1...119, -// according to the i2c scanner by Nick Gammon -// http://www.gammon.com.au/forum/?id=10896 -// Version 5, March 28, 2013 -// As version 4, but address scans now to 127. -// A sensor seems to use address 120. -// Version 6, November 27, 2015. -// Added waiting for the Leonardo serial communication. -// -// -// This sketch tests the standard 7-bit addresses -// Devices with higher bit address might not be seen properly. -// +/** ========================================================================= + * @file i2c_scanner.ino + * @brief Testing sketch to scan for attached I2C devices + * + * Version 1 + * This program (or code that looks like it) + * can be found in many places. + * For example on the Arduino.cc forum. + * The original author is not know. + * Version 2, Juni 2012, Using Arduino 1.0.1 + * Adapted to be as simple as possible by Arduino.cc user Krodal + * Version 3, Feb 26 2013 + * V3 by louarnold + * Version 4, March 3, 2013, Using Arduino 1.0.3 + * by Arduino.cc user Krodal. + * Changes by louarnold removed. + * Scanning addresses changed from 0...127 to 1...119, + * according to the i2c scanner by Nick Gammon + * http://www.gammon.com.au/forum/?id=10896 + * Version 5, March 28, 2013 + * As version 4, but address scans now to 127. + * A sensor seems to use address 120. + * Version 6, November 27, 2015. + * Added waiting for the Leonardo serial communication. + * + * + * This sketch tests the standard 7-bit addresses. + * Devices with higher bit address might not be seen properly. + * ======================================================================= */ #include #include diff --git a/extras/i2c_warmUp/i2c_warmUp.ino b/extras/i2c_warmUp/i2c_warmUp.ino index 998e74860..256f25548 100644 --- a/extras/i2c_warmUp/i2c_warmUp.ino +++ b/extras/i2c_warmUp/i2c_warmUp.ino @@ -1,3 +1,9 @@ +/** ========================================================================= + * @file i2c_warmUp.ino + * @brief Testing sketch to see how long an attached I2C device takes to + * begin to respond to commands. + * ======================================================================= */ + #include #include diff --git a/extras/interrupt_counter/interrupt_counter.ino b/extras/interrupt_counter/interrupt_counter.ino index 5dec9af2b..e62419854 100644 --- a/extras/interrupt_counter/interrupt_counter.ino +++ b/extras/interrupt_counter/interrupt_counter.ino @@ -1,3 +1,8 @@ +/** ========================================================================= + * @file interrupt_counter.ino + * @brief Testing sketch counting pin change interrupts. + * ======================================================================= */ + #include #define EI_ARDUINO_INTERRUPTED_PIN diff --git a/extras/mega_serial_spy/mega_serial_spy.ino b/extras/mega_serial_spy/mega_serial_spy.ino index 7d9316369..5c910c9d6 100644 --- a/extras/mega_serial_spy/mega_serial_spy.ino +++ b/extras/mega_serial_spy/mega_serial_spy.ino @@ -1,3 +1,9 @@ +/** ========================================================================= + * @file mega_serial_spy.ino + * @brief Testing sketch to run on an Arduino Mega to print all output from + * connected serial ports to the terminal. + * ======================================================================= */ + #include void changeBauds(void) { diff --git a/extras/oneWireSearch/oneWireSearch.ino b/extras/oneWireSearch/oneWireSearch.ino index 8a7872d2e..718205b83 100644 --- a/extras/oneWireSearch/oneWireSearch.ino +++ b/extras/oneWireSearch/oneWireSearch.ino @@ -1,19 +1,20 @@ -// -// FILE: oneWireSearch.ino -// AUTHOR: Rob Tillaart -// VERSION: 0.1.02 -// PURPOSE: scan for 1-Wire devices + code snippet generator -// DATE: 2015-june-30 -// URL: http://forum.arduino.cc/index.php?topic=333923 -// -// inspired by -// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html -// -// Released to the public domain -// -// 0.1.00 initial version -// 0.1.01 first published version -// 0.1.02 small output changes +/** ========================================================================= + * @file oneWireSearch.ino + * @author Rob Tillaart + * VERSION: 0.1.02 + * @brief scan for 1-Wire devices + code snippet generator + * DATE: 2015-june-30 + * URL: http://forum.arduino.cc/index.php?topic=333923 + * + * inspired by + * http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html + * + * Released to the public domain + * + * 0.1.00 initial version + * 0.1.01 first published version + * 0.1.02 small output changes + * ======================================================================= */ #include #include diff --git a/extras/powerOn/powerOn.ino b/extras/powerOn/powerOn.ino index ae244aeaf..e6ce8130b 100644 --- a/extras/powerOn/powerOn.ino +++ b/extras/powerOn/powerOn.ino @@ -1,3 +1,9 @@ +/** ========================================================================= + * @file powerOn.ino + * @brief Testing sketch that simply turns on power to the sensors on the + * Mayfly. + * ======================================================================= */ + #include int8_t powerPin = 22; diff --git a/extras/resetBee/resetBee.ino b/extras/resetBee/resetBee.ino index f08874ec5..275d7aeaa 100644 --- a/extras/resetBee/resetBee.ino +++ b/extras/resetBee/resetBee.ino @@ -1,3 +1,8 @@ +/** ========================================================================= + * @file resetBee.ino + * @brief Testing sketch to fully reset an XBee + * ======================================================================= */ + #include void setup() { diff --git a/extras/sdi12_address_change/sdi12_address_change.ino b/extras/sdi12_address_change/sdi12_address_change.ino index 4b5a44690..677e17574 100644 --- a/extras/sdi12_address_change/sdi12_address_change.ino +++ b/extras/sdi12_address_change/sdi12_address_change.ino @@ -1,52 +1,15 @@ -/* -######################## -# OVERVIEW # -######################## - - Example B: Changing the address of a sensor. - - This is a simple demonstration of the SDI-12 library for arduino. - It discovers the address of the attached sensor and allows you to change it. - -######################### -# THE CIRCUIT # -######################### - - The circuit: You should not have more than one SDI-12 device attached for this -example. - - See: - https://raw.github.com/Kevin-M-Smith/SDI-12-Circuit-Diagrams/master/basic_setup_no_usb.png - or - https://raw.github.com/Kevin-M-Smith/SDI-12-Circuit-Diagrams/master/compat_setup_usb.png - -########################### -# COMPATIBILITY # -########################### - - This library requires the use of pin change interrupts (PCINT). - Not all Arduino boards have the same pin capabilities. - The known compatibile pins for common variants are shown below. - - Arduino Uno: All pins. - - Arduino Mega or Mega 2560: - 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), - A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69). - - Arduino Leonardo: - 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI) - -######################### -# RESOURCES # -######################### - - Written by Kevin M. Smith in 2013. - Contact: SDI12@ethosengineering.org - - The SDI-12 specification is available at: http://www.sdi-12.org/ - The library is available at: https://github.com/EnviroDIY/Arduino-SDI-12 -*/ +/** + * @file sdi12_address_change.ino + * @copyright Stroud Water Research Center + * This example is published under the BSD-3 license. + * @author Kevin M.Smith + * @date August 2013 + * + * @brief Copy of SDI-12 Example B: Changing the Address of your SDI-12 Sensor + * + * The SDI-12 specification is available at: http://www.sdi-12.org/ + * The library is available at: https://github.com/EnviroDIY/Arduino-SDI-12 + */ #include From 522ac8a8edc876e96c9e6a4dd40fa3df3f90abce Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 14 Jun 2024 13:21:25 -0400 Subject: [PATCH 083/138] Regroup modem defines Signed-off-by: Sara Damiano --- src/modems/DigiXBee.h | 20 +++++++++---- src/modems/DigiXBee3GBypass.h | 5 ++-- src/modems/DigiXBeeCellularTransparent.h | 6 ++-- src/modems/DigiXBeeLTEBypass.h | 6 ++-- src/modems/DigiXBeeWifi.h | 13 +++++++-- src/modems/EspressifESP8266.h | 36 ++++++++++++++---------- src/modems/QuectelBG96.h | 33 +++++++++++++--------- src/modems/SIMComSIM7000.h | 33 +++++++++++++--------- src/modems/SIMComSIM7080.h | 33 +++++++++++++--------- src/modems/SIMComSIM800.h | 33 +++++++++++++--------- src/modems/SequansMonarch.h | 33 +++++++++++++--------- src/modems/Sodaq2GBeeR6.h | 26 ++++++++++------- src/modems/SodaqUBeeR410M.h | 33 +++++++++++++--------- src/modems/SodaqUBeeU201.h | 35 +++++++++++++---------- 14 files changed, 203 insertions(+), 142 deletions(-) diff --git a/src/modems/DigiXBee.h b/src/modems/DigiXBee.h index 22ed69fdb..4edf2c956 100644 --- a/src/modems/DigiXBee.h +++ b/src/modems/DigiXBee.h @@ -35,6 +35,7 @@ * @subsection modem_digi_raw_pins_1x Pin Numbers for connecting Digi XBee's Directly to a Mayfly v1.x * * This applies to _all_ Digi XBees and XBee3's when attached directly to the Mayfly's bee slot. + * * @code{cpp} * const int8_t modemVccPin = 18; // MCU pin controlling modem power * const bool useCTSforStatus = true; // Flag to use the XBee `CTS` pin for status @@ -47,6 +48,7 @@ * @subsection modem_digi_raw_pins Pin Numbers for connecting Digi XBee's Directly to a Mayfly v0.3-v0.5c * * This applies to _all_ Digi XBees and XBee3's when attached directly to the Mayfly's bee slot. + * * @code{cpp} * const int8_t modemVccPin = -1; // MCU pin controlling modem power * const bool useCTSforStatus = true; // Flag to use the XBee `CTS` pin for status @@ -97,9 +99,20 @@ #define MS_DEBUGGING_STD "DigiXBee" #endif +// Included Dependencies +#include "ModSensorDebugger.h" +#undef MS_DEBUGGING_STD +#include "LoggerModem.h" + /** @ingroup modem_digi */ /**@{*/ +/** + * @anchor modem_digi_pins_timing + * @name Modem Pin Settings and Timing + * The timing and pin level settings for a Digi XBee + */ +/**@{*/ /** * @brief The loggerModem::_statusTime_ms. * @@ -164,12 +177,7 @@ * R4 on the LTE-M model takes nearly that long to shut down. */ #define XBEE_DISCONNECT_TIME_MS 15000L - -// Included Dependencies -#include "ModSensorDebugger.h" -#undef MS_DEBUGGING_STD -#include "LoggerModem.h" - +/**@}*/ /** * @brief The parent class for all [Digi XBee and XBee3](@ref modem_digi) wifi diff --git a/src/modems/DigiXBee3GBypass.h b/src/modems/DigiXBee3GBypass.h index fbb62bdd9..4dfe8472f 100644 --- a/src/modems/DigiXBee3GBypass.h +++ b/src/modems/DigiXBee3GBypass.h @@ -58,9 +58,6 @@ #define MS_DEBUGGING_STD "DigiXBee3GBypass" #endif -/** @ingroup modem_digi_3g_bypass */ -/**@{*/ - /** * @brief The modem type for the underlying TinyGSM library. */ @@ -83,6 +80,8 @@ #include #endif +/** @ingroup modem_digi_3g_bypass */ +/**@{*/ /** * @brief The loggerModem subclass for [Digi Cellular XBee's](@ref modem_digi) diff --git a/src/modems/DigiXBeeCellularTransparent.h b/src/modems/DigiXBeeCellularTransparent.h index 33190465e..c7e67aea6 100644 --- a/src/modems/DigiXBeeCellularTransparent.h +++ b/src/modems/DigiXBeeCellularTransparent.h @@ -81,9 +81,6 @@ #define MS_DEBUGGING_STD "DigiXBeeCellularTransparent" #endif -/** @ingroup modem_digi_cellular */ -/**@{*/ - /** * @brief The modem type for the underlying TinyGSM library. */ @@ -106,6 +103,9 @@ #include #endif +/** @ingroup modem_digi_cellular */ +/**@{*/ + /** * @brief The class for any of * [Digi Cellular XBee or XBee3](@ref modem_digi) modules operating in Digi's diff --git a/src/modems/DigiXBeeLTEBypass.h b/src/modems/DigiXBeeLTEBypass.h index 6a952f6a8..7020e125f 100644 --- a/src/modems/DigiXBeeLTEBypass.h +++ b/src/modems/DigiXBeeLTEBypass.h @@ -74,9 +74,6 @@ #define MS_DEBUGGING_STD "DigiXBeeLTEBypass" #endif -/** @ingroup modem_digi_lte_bypass */ -/**@{*/ - /** * @brief The modem type for the underlying TinyGSM library. */ @@ -99,6 +96,9 @@ #include #endif +/** @ingroup modem_digi_lte_bypass */ +/**@{*/ + /** * @brief The class for any of Digi's cellular LTE-M [XBee3](@ref modem_digi) * modules operating in [Digi's "bypass" mode](@ref modem_digi_lte_bypass). diff --git a/src/modems/DigiXBeeWifi.h b/src/modems/DigiXBeeWifi.h index 11c7c7110..dd4e4a368 100644 --- a/src/modems/DigiXBeeWifi.h +++ b/src/modems/DigiXBeeWifi.h @@ -55,9 +55,6 @@ #define MS_DEBUGGING_DEEP "DigiXBeeWifi" #endif -/** @ingroup modem_digi_wifi */ -/**@{*/ - /** * @brief The modem type for the underlying TinyGSM library. */ @@ -80,11 +77,21 @@ #include #endif +/** @ingroup modem_digi_wifi */ +/**@{*/ + +/** + * @anchor modem_digi_wifi_config + * @name Configuration Defines + * Defines to configure if and when to reset the WiFi XBee + */ +/**@{*/ /** * @brief This causes the WiFi XBee to reset after this number of transmission * attempts */ #define XBEE_RESET_THRESHOLD 4 +/**@}*/ /** * @brief The class for the [Digi XBee](@ref modem_digi) diff --git a/src/modems/EspressifESP8266.h b/src/modems/EspressifESP8266.h index 593f5aeaf..be33c4fb5 100644 --- a/src/modems/EspressifESP8266.h +++ b/src/modems/EspressifESP8266.h @@ -78,9 +78,6 @@ #define MS_DEBUGGING_STD "EspressifESP8266" #endif -/** @ingroup modem_esp8266 */ -/**@{*/ - /** * @brief The modem type for the underlying TinyGSM library. */ @@ -92,7 +89,25 @@ #define TINY_GSM_RX_BUFFER 64 #endif +// Included Dependencies +#include "ModSensorDebugger.h" +#undef MS_DEBUGGING_STD +#include "TinyGsmClient.h" +#include "LoggerModem.h" + +#ifdef MS_ESPRESSIFESP8266_DEBUG_DEEP +#include +#endif + +/** @ingroup modem_esp8266 */ +/**@{*/ +/** + * @anchor modem_esp8266_pins_timing + * @name Modem Pin Settings and Timing + * The timing and pin level settings for an ESP8266 (or ESP32) + */ +/**@{*/ /** * @brief The loggerModem::_statusLevel. * @@ -179,16 +194,7 @@ * credentials. */ #define ESP8266_RECONNECT_TIME_MS 2500 - -// Included Dependencies -#include "ModSensorDebugger.h" -#undef MS_DEBUGGING_STD -#include "TinyGsmClient.h" -#include "LoggerModem.h" - -#ifdef MS_ESPRESSIFESP8266_DEBUG_DEEP -#include -#endif +/**@}*/ /** * @brief The loggerModem subclass for any breakout of the @@ -278,11 +284,11 @@ class EspressifESP8266 : public loggerModem { const char* _ssid; ///< Internal reference to the WiFi SSID const char* _pwd; ///< Internal reference to the WiFi password }; +/**@}*/ /** - * @brief typedef to avoid confusion for users + * @brief Assign EspressifESP32 as type EspressifESP8266 to avoid user confusion */ typedef EspressifESP8266 EspressifESP32; -/**@}*/ #endif // SRC_MODEMS_ESPRESSIFESP8266_H_ diff --git a/src/modems/QuectelBG96.h b/src/modems/QuectelBG96.h index f7b0e5284..69994d983 100644 --- a/src/modems/QuectelBG96.h +++ b/src/modems/QuectelBG96.h @@ -70,9 +70,6 @@ #define MS_DEBUGGING_STD "QuectelBG96" #endif -/** @ingroup modem_bg96 */ -/**@{*/ - /** * @brief The modem type for the underlying TinyGSM library. */ @@ -84,7 +81,25 @@ #define TINY_GSM_RX_BUFFER 64 #endif +// Included Dependencies +#include "ModSensorDebugger.h" +#undef MS_DEBUGGING_STD +#include "TinyGsmClient.h" +#include "LoggerModem.h" + +#ifdef MS_QUECTELBG96_DEBUG_DEEP +#include +#endif + +/** @ingroup modem_bg96 */ +/**@{*/ +/** + * @anchor modem_bg96_pins_timing + * @name Modem Pin Settings and Timing + * The timing and pin level settings for a Quectel BG96 + */ +/**@{*/ /** * @brief The loggerModem::_statusLevel. * @@ -148,17 +163,7 @@ * Documentation for the BG96 says to allow >2s for clean shutdown. */ #define BG96_DISCONNECT_TIME_MS 5000L - -// Included Dependencies -#include "ModSensorDebugger.h" -#undef MS_DEBUGGING_STD -#include "TinyGsmClient.h" -#include "LoggerModem.h" - -#ifdef MS_QUECTELBG96_DEBUG_DEEP -#include -#endif - +/**@}*/ /** * @brief The loggerModem subclass for Dragino, Nimbelink, or any other module diff --git a/src/modems/SIMComSIM7000.h b/src/modems/SIMComSIM7000.h index b4f71f6c8..7e5680e37 100644 --- a/src/modems/SIMComSIM7000.h +++ b/src/modems/SIMComSIM7000.h @@ -59,9 +59,6 @@ #define MS_DEBUGGING_STD "SIMComSIM7000" #endif -/** @ingroup modem_sim7000 */ -/**@{*/ - /** * @brief The modem type for the underlying TinyGSM library. */ @@ -73,7 +70,25 @@ #define TINY_GSM_RX_BUFFER 64 #endif +// Included Dependencies +#include "ModSensorDebugger.h" +#undef MS_DEBUGGING_STD +#include "TinyGsmClient.h" +#include "LoggerModem.h" + +#ifdef MS_SIMCOMSIM7000_DEBUG_DEEP +#include +#endif + +/** @ingroup modem_sim7000 */ +/**@{*/ +/** + * @anchor modem_sim7000_pins_timing + * @name Modem Pin Settings and Timing + * The timing and pin level settings for a SIMCom SIM7000 + */ +/**@{*/ /** * @brief The loggerModem::_statusLevel. * @@ -139,17 +154,7 @@ * SIM7000 power down (gracefully) takes 1.8-6.9 sec. */ #define SIM7000_DISCONNECT_TIME_MS 7000L - -// Included Dependencies -#include "ModSensorDebugger.h" -#undef MS_DEBUGGING_STD -#include "TinyGsmClient.h" -#include "LoggerModem.h" - -#ifdef MS_SIMCOMSIM7000_DEBUG_DEEP -#include -#endif - +/**@}*/ /** * @brief The loggerModem subclass for Botletics, And1, and other modules based diff --git a/src/modems/SIMComSIM7080.h b/src/modems/SIMComSIM7080.h index e7847924f..d1bb5cb81 100644 --- a/src/modems/SIMComSIM7080.h +++ b/src/modems/SIMComSIM7080.h @@ -51,9 +51,6 @@ #define MS_DEBUGGING_STD "SIMComSIM7080" #endif -/** @ingroup modem_sim7080 */ -/**@{*/ - /** * @brief The modem type for the underlying TinyGSM library. */ @@ -65,7 +62,25 @@ #define TINY_GSM_RX_BUFFER 64 #endif +// Included Dependencies +#include "ModSensorDebugger.h" +#undef MS_DEBUGGING_STD +#include "TinyGsmClient.h" +#include "LoggerModem.h" + +#ifdef MS_SIMCOMSIM7080_DEBUG_DEEP +#include +#endif + +/** @ingroup modem_sim7080 */ +/**@{*/ +/** + * @anchor modem_sim7080_pins_timing + * @name Modem Pin Settings and Timing + * The timing and pin level settings for a SIMCom SIM7080 + */ +/**@{*/ /** * @brief The loggerModem::_statusLevel. * @@ -134,17 +149,7 @@ * SIM7080 power down (gracefully) takes 1.8-2 sec. */ #define SIM7080_DISCONNECT_TIME_MS 2000L - -// Included Dependencies -#include "ModSensorDebugger.h" -#undef MS_DEBUGGING_STD -#include "TinyGsmClient.h" -#include "LoggerModem.h" - -#ifdef MS_SIMCOMSIM7080_DEBUG_DEEP -#include -#endif - +/**@}*/ /** * @brief The loggerModem subclass for modules based on the [SIMCOM diff --git a/src/modems/SIMComSIM800.h b/src/modems/SIMComSIM800.h index dfdceab8b..5553a3ba1 100644 --- a/src/modems/SIMComSIM800.h +++ b/src/modems/SIMComSIM800.h @@ -63,9 +63,6 @@ #define MS_DEBUGGING_STD "SIMComSIM800" #endif -/** @ingroup modem_sim800 */ -/**@{*/ - /** * @brief The modem type for the underlying TinyGSM library. */ @@ -77,7 +74,25 @@ #define TINY_GSM_RX_BUFFER 64 #endif +// Included Dependencies +#include "ModSensorDebugger.h" +#undef MS_DEBUGGING_STD +#include "TinyGsmClient.h" +#include "LoggerModem.h" + +#ifdef MS_SIMCOMSIM800_DEBUG_DEEP +#include +#endif + +/** @ingroup modem_sim800 */ +/**@{*/ +/** + * @anchor modem_sim800_pins_timing + * @name Modem Pin Settings and Timing + * The timing and pin level settings for a SIMCom SIM800 + */ +/**@{*/ /** * @brief The loggerModem::_statusLevel. * @@ -141,17 +156,7 @@ * shutdown in case it is not monitored. */ #define SIM800_DISCONNECT_TIME_MS 15000L - -// Included Dependencies -#include "ModSensorDebugger.h" -#undef MS_DEBUGGING_STD -#include "TinyGsmClient.h" -#include "LoggerModem.h" - -#ifdef MS_SIMCOMSIM800_DEBUG_DEEP -#include -#endif - +/**@}*/ /** * @brief The loggerModem subclass for the Adafruit Fona 2G, the Sodaq GPRSBeeR4 diff --git a/src/modems/SequansMonarch.h b/src/modems/SequansMonarch.h index 2162c2412..afcc48456 100644 --- a/src/modems/SequansMonarch.h +++ b/src/modems/SequansMonarch.h @@ -64,9 +64,6 @@ #define MS_DEBUGGING_STD "SequansMonarch" #endif -/** @ingroup modem_monarch */ -/**@{*/ - /** * @brief The modem type for the underlying TinyGSM library. */ @@ -78,7 +75,25 @@ #define TINY_GSM_RX_BUFFER 64 #endif +// Included Dependencies +#include "ModSensorDebugger.h" +#undef MS_DEBUGGING_STD +#include "TinyGsmClient.h" +#include "LoggerModem.h" + +#ifdef MS_SEQUANSMONARCH_DEBUG_DEEP +#include +#endif + +/** @ingroup modem_monarch */ +/**@{*/ +/** + * @anchor modem_monarch_pins_timing + * @name Modem Pin Settings and Timing + * The timing and pin level settings for a Sequans Monarch + */ +/**@{*/ /** * @brief The loggerModem::_statusLevel. * @@ -168,17 +183,7 @@ * monitored. */ #define VZM20Q_DISCONNECT_TIME_MS 15000L - -// Included Dependencies -#include "ModSensorDebugger.h" -#undef MS_DEBUGGING_STD -#include "TinyGsmClient.h" -#include "LoggerModem.h" - -#ifdef MS_SEQUANSMONARCH_DEBUG_DEEP -#include -#endif - +/**@}*/ /** * @brief The loggerModem subclass for Nimbelink or other modules based on the diff --git a/src/modems/Sodaq2GBeeR6.h b/src/modems/Sodaq2GBeeR6.h index 53a6f459d..07fd95bc1 100644 --- a/src/modems/Sodaq2GBeeR6.h +++ b/src/modems/Sodaq2GBeeR6.h @@ -69,9 +69,24 @@ #define MS_DEBUGGING_STD "Sodaq2GBeeR6" #endif +// Included Dependencies +#include "ModSensorDebugger.h" +#undef MS_DEBUGGING_STD +#include "SIMComSIM800.h" + +#ifdef MS_SODAQ2GBEER6_DEBUG_DEEP +#include +#endif + /** @ingroup modem_gprsbee */ /**@{*/ +/** + * @anchor modem_gprsbee_pins_timing + * @name Modem Pin Settings and Timing + * The timing and pin level settings for a GPRSBee + */ +/**@{*/ /** * @brief The loggerModem::_wakeDelayTime_ms. * @@ -79,16 +94,7 @@ * warm-up time needed */ #define S2GBR6_WAKE_DELAY_MS 0 - -// Included Dependencies -#include "ModSensorDebugger.h" -#undef MS_DEBUGGING_STD -#include "SIMComSIM800.h" - -#ifdef MS_SODAQ2GBEER6_DEBUG_DEEP -#include -#endif - +/**@}*/ /** * @brief The loggerModem subclass for the [Sodaq 2GBee](@ref modem_gprsbee) diff --git a/src/modems/SodaqUBeeR410M.h b/src/modems/SodaqUBeeR410M.h index 9539a01d1..905d3555e 100644 --- a/src/modems/SodaqUBeeR410M.h +++ b/src/modems/SodaqUBeeR410M.h @@ -120,9 +120,6 @@ #define MS_DEBUGGING_STD "SodaqUBeeR410M" #endif -/** @ingroup modem_ubee_ltem */ -/**@{*/ - /** * @brief The modem type for the underlying TinyGSM library. */ @@ -134,7 +131,25 @@ #define TINY_GSM_RX_BUFFER 64 #endif +// Included Dependencies +#include "ModSensorDebugger.h" +#undef MS_DEBUGGING_STD +#include "TinyGsmClient.h" +#include "LoggerModem.h" + +#ifdef MS_SODAQUBEER410M_DEBUG_DEEP +#include +#endif + +/** @ingroup modem_ubee_ltem */ +/**@{*/ +/** + * @anchor modem_ubee_ltem_pins_timing + * @name Modem Pin Settings and Timing + * The timing and pin level settings for a Sodaq UBee R410M + */ +/**@{*/ /** * @brief The loggerModem::_statusLevel. * @@ -197,17 +212,7 @@ * low. We allow up to 15 seconds for shutdown in case it is not monitored. */ #define R410M_DISCONNECT_TIME_MS 15000L - -// Included Dependencies -#include "ModSensorDebugger.h" -#undef MS_DEBUGGING_STD -#include "TinyGsmClient.h" -#include "LoggerModem.h" - -#ifdef MS_SODAQUBEER410M_DEBUG_DEEP -#include -#endif - +/**@}*/ /** * @brief The loggerModem subclass for the diff --git a/src/modems/SodaqUBeeU201.h b/src/modems/SodaqUBeeU201.h index dc7edc3b0..00d0e7002 100644 --- a/src/modems/SodaqUBeeU201.h +++ b/src/modems/SodaqUBeeU201.h @@ -60,9 +60,6 @@ #define MS_DEBUGGING_STD "SodaqUBeeU201" #endif -/** @ingroup modem_ubee_3g */ -/**@{*/ - /** * @brief The modem type for the underlying TinyGSM library. */ @@ -74,6 +71,25 @@ #define TINY_GSM_RX_BUFFER 64 #endif +// Included Dependencies +#include "ModSensorDebugger.h" +#undef MS_DEBUGGING_STD +#include "TinyGsmClient.h" +#include "LoggerModem.h" + +#ifdef MS_SODAQUBEEU201_DEBUG_DEEP +#include +#endif + +/** @ingroup modem_ubee_3g */ +/**@{*/ + +/** + * @anchor modem_ubee_3g_pins_timing + * @name Modem Pin Settings and Timing + * The timing and pin level settings for a Sodaq UBee U201 + */ +/**@{*/ /** * @brief The loggerModem::_statusLevel. * @@ -137,18 +153,7 @@ * low. We allow up to 15 seconds for shutdown in case it is not monitored. */ #define U201_DISCONNECT_TIME_MS 15000L - - -// Included Dependencies -#include "ModSensorDebugger.h" -#undef MS_DEBUGGING_STD -#include "TinyGsmClient.h" -#include "LoggerModem.h" - -#ifdef MS_SODAQUBEEU201_DEBUG_DEEP -#include -#endif - +/**@}*/ /** * @brief The loggerModem subclass for the [2G/3G](@ref modem_ubee_3g) From 55a06e7a0cc2174f2348cc7c67128be6a530258b Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 14 Jun 2024 13:33:37 -0400 Subject: [PATCH 084/138] Regroup sensor defines Signed-off-by: Sara Damiano --- src/sensors/AOSongAM2315.h | 8 +++- src/sensors/AOSongDHT.h | 8 +++- src/sensors/AnalogElecConductivity.h | 62 +++++++++++++++++----------- src/sensors/ApogeeSQ212.h | 39 +++++++++++------ src/sensors/AtlasScientificCO2.h | 21 ++++++++-- src/sensors/AtlasScientificDO.h | 25 +++++++---- src/sensors/AtlasScientificEC.h | 22 ++++++++-- src/sensors/AtlasScientificORP.h | 22 +++++++--- src/sensors/AtlasScientificRTD.h | 28 +++++++++---- src/sensors/AtlasScientificpH.h | 21 ++++++++-- src/sensors/BoschBME280.h | 26 +++++++++--- src/sensors/BoschBMP3xx.h | 26 +++++++++--- src/sensors/CampbellClariVUE10.h | 8 +++- src/sensors/CampbellOBS3.h | 22 ++++++++-- src/sensors/CampbellRainVUE10.h | 8 +++- src/sensors/Decagon5TM.h | 8 +++- src/sensors/DecagonCTD.h | 8 +++- src/sensors/DecagonES2.h | 8 +++- src/sensors/EverlightALSPT19.h | 29 +++++++++++-- src/sensors/FreescaleMPL115A2.h | 8 +++- src/sensors/GroPointGPLP8.h | 8 +++- src/sensors/InSituRDO.h | 8 +++- src/sensors/InSituTrollSdi12a.h | 11 ++++- src/sensors/KellerAcculevel.h | 1 - src/sensors/KellerNanolevel.h | 1 - src/sensors/KellerParent.h | 8 +++- src/sensors/MaxBotixSonar.h | 8 +++- src/sensors/MaximDS18.h | 8 +++- src/sensors/MaximDS3231.h | 8 +++- src/sensors/MeaSpecMS5803.h | 8 +++- src/sensors/MeterHydros21.h | 8 +++- src/sensors/MeterTeros11.h | 8 +++- src/sensors/PaleoTerraRedox.h | 21 ++++++++-- src/sensors/ProcessorStats.h | 9 +++- src/sensors/RainCounterI2C.h | 8 +++- src/sensors/SensirionSHT4x.h | 8 +++- src/sensors/TIADS1x15.h | 21 ++++++++-- src/sensors/TIINA219.h | 21 ++++++++-- src/sensors/TallyCounterI2C.h | 21 ++++++++-- src/sensors/TurnerCyclops.h | 21 ++++++++-- src/sensors/VegaPuls21.h | 8 +++- src/sensors/YosemitechY4000.h | 8 +++- src/sensors/YosemitechY504.h | 8 +++- src/sensors/YosemitechY510.h | 8 +++- src/sensors/YosemitechY511.h | 8 +++- src/sensors/YosemitechY514.h | 8 +++- src/sensors/YosemitechY520.h | 8 +++- src/sensors/YosemitechY532.h | 8 +++- src/sensors/YosemitechY533.h | 8 +++- src/sensors/YosemitechY551.h | 8 +++- src/sensors/YosemitechY560.h | 8 +++- src/sensors/YosemitechY700.h | 8 +++- src/sensors/ZebraTechDOpto.h | 16 ++++--- 53 files changed, 584 insertions(+), 150 deletions(-) diff --git a/src/sensors/AOSongAM2315.h b/src/sensors/AOSongAM2315.h index 7fa3b61c0..4313f5bb7 100644 --- a/src/sensors/AOSongAM2315.h +++ b/src/sensors/AOSongAM2315.h @@ -73,11 +73,17 @@ /** @ingroup sensor_am2315 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_am2315_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by an AOSong AM2315 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the AM2315 can report 2 values. #define AM2315_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define AM2315_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_am2315_timing diff --git a/src/sensors/AOSongDHT.h b/src/sensors/AOSongDHT.h index 8fc8051d3..7daabf22d 100644 --- a/src/sensors/AOSongDHT.h +++ b/src/sensors/AOSongDHT.h @@ -95,11 +95,17 @@ static const uint8_t AM2301{21}; /**< AM2301 */ /** @ingroup sensor_dht */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_dht_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by an AOSong DHT + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the DHT can report 3 values. #define DHT_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define DHT_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_dht_timing diff --git a/src/sensors/AnalogElecConductivity.h b/src/sensors/AnalogElecConductivity.h index a0cb40c79..601163055 100644 --- a/src/sensors/AnalogElecConductivity.h +++ b/src/sensors/AnalogElecConductivity.h @@ -43,6 +43,7 @@ * of known resistance (R1) and then to an analog pin to measure the voltage. * * So the circuit is: + * * @code{.unparsed} * Vin (sensor power) --- R1 --- power cord --- Vout * | @@ -133,6 +134,10 @@ #ifndef SRC_SENSORS_ANALOGELECCONDUCTIVITY_H_ #define SRC_SENSORS_ANALOGELECCONDUCTIVITY_H_ +// Debugging Statement +// #define MS_ANALOGELECCONDUCTIVITY_DEBUG +// #define MS_ANALOGELECCONDUCTIVITY_DEBUG_DEEP + #ifdef MS_ANALOGELECCONDUCTIVITY_DEBUG #define MS_DEBUGGING_STD "AnalogElecConductivity" #endif @@ -151,7 +156,13 @@ /** @ingroup sensor_analog_cond */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_analog_cond_parts_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the analog conductivity + * sensor + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; we only get one value from the analog /// conductivity sensor. #define ANALOGELECCONDUCTIVITY_NUM_VARIABLES 1 @@ -159,35 +170,13 @@ /// though we recommend users include a temperature sensor and calculate /// specific conductance in their own program. #define ANALOGELECCONDUCTIVITY_INC_CALC_VARIABLES 0 - -/** - * @anchor sensor_analog_cond_parts_timing - * @name Sensor Timing - * The timing for analog conductivity via resistance. - */ -/**@{*/ -/// @brief Sensor::_warmUpTime_ms; giving 2ms for warm-up. -#define ANALOGELECCONDUCTIVITY_WARM_UP_TIME_MS 2 -/// @brief Sensor::_stabilizationTime_ms; we give just a tiny delay for -/// stabilization. -#define ANALOGELECCONDUCTIVITY_STABILIZATION_TIME_MS 1 -/** - * @brief Sensor::_measurementTime_ms; we assume the analog voltage is measured - * instantly. - * - * It's not really *quite* instantly, but it is very fast and the time to - * measure is included in the read function. - * On ATmega based boards (UNO, Nano, Mini, Mega), it takes about 100 - * microseconds (0.0001 s) to read an analog input, so the maximum reading rate - * is about 10,000 times a second. - */ -#define ANALOGELECCONDUCTIVITY_MEASUREMENT_TIME_MS 0 /**@}*/ /** * @anchor sensor_analog_cond_parts_config * @name Configuration Defines - * Defines to help configure the outputs from the home-made conductivity sensor. + * Defines to help configure the range and resolution of the home-made + * conductivity sensor depending on the processor and ADC in use. */ /**@{*/ #if !defined ANALOG_EC_ADC_RESOLUTION || defined(DOXYGEN) @@ -281,6 +270,29 @@ #endif // SENSOREC_KONST_DEF /**@}*/ +/** + * @anchor sensor_analog_cond_parts_timing + * @name Sensor Timing + * The timing for analog conductivity via resistance. + */ +/**@{*/ +/// @brief Sensor::_warmUpTime_ms; giving 2ms for warm-up. +#define ANALOGELECCONDUCTIVITY_WARM_UP_TIME_MS 2 +/// @brief Sensor::_stabilizationTime_ms; we give just a tiny delay for +/// stabilization. +#define ANALOGELECCONDUCTIVITY_STABILIZATION_TIME_MS 1 +/** + * @brief Sensor::_measurementTime_ms; we assume the analog voltage is measured + * instantly. + * + * It's not really *quite* instantly, but it is very fast and the time to + * measure is included in the read function. + * On ATmega based boards (UNO, Nano, Mini, Mega), it takes about 100 + * microseconds (0.0001 s) to read an analog input, so the maximum reading rate + * is about 10,000 times a second. + */ +#define ANALOGELECCONDUCTIVITY_MEASUREMENT_TIME_MS 0 +/**@}*/ /** * @anchor sensor_analog_cond_parts_ec * @name Electrical Conductance diff --git a/src/sensors/ApogeeSQ212.h b/src/sensors/ApogeeSQ212.h index 48102acbe..0e2e5e773 100644 --- a/src/sensors/ApogeeSQ212.h +++ b/src/sensors/ApogeeSQ212.h @@ -92,12 +92,37 @@ /** @ingroup sensor_sq212 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_sq212_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the Apogee SQ-212 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the SQ212 can report 2 values, raw /// voltage and calculated PAR. #define SQ212_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; PAR is calculated from the raw voltage. #define SQ212_INC_CALC_VARIABLES 1 +/**@}*/ + +/** + * @anchor sensor_sq212_config + * @name Configuration Defines + * Defines to set the calibration of the SQ-212 and the address of the ADD. + */ +/**@{*/ +#ifndef SQ212_CALIBRATION_FACTOR || defined(DOXYGEN) +/** + * @brief The calibration factor between output in volts and PAR + * (microeinsteinPerSquareMeterPerSecond) 1 µmol mˉ² sˉ¹ per mV (reciprocal of + * sensitivity) + */ +#define SQ212_CALIBRATION_FACTOR 1 +#endif + +/// The assumed address of the ADS1115, 1001 000 (ADDR = GND) +#define ADS1115_ADDRESS 0x48 +/**@}*/ /** * @anchor sensor_sq212_timing @@ -203,18 +228,6 @@ #endif /**@}*/ -/** - * @brief The calibration factor between output in volts and PAR - * (microeinsteinPerSquareMeterPerSecond) 1 µmol mˉ² sˉ¹ per mV (reciprocal of - * sensitivity) - */ -#ifndef SQ212_CALIBRATION_FACTOR -#define SQ212_CALIBRATION_FACTOR 1 -#endif - -/// The assumed address of the ADS1115, 1001 000 (ADDR = GND) -#define ADS1115_ADDRESS 0x48 - /** * @brief The Sensor sub-class for the [Apogee SQ-212](@ref sensor_sq212) sensor * diff --git a/src/sensors/AtlasScientificCO2.h b/src/sensors/AtlasScientificCO2.h index fdaa99cea..fe3815fcf 100644 --- a/src/sensors/AtlasScientificCO2.h +++ b/src/sensors/AtlasScientificCO2.h @@ -63,17 +63,30 @@ #include "VariableBase.h" #include "sensors/AtlasParent.h" -// Sensor Specific Defines /** @ingroup sensor_atlas_co2 */ /**@{*/ -/// Default I2C address is 0x69 (105) -#define ATLAS_CO2_I2C_ADDR 0x69 // 105 - +/** + * @anchor sensor_atlas_co2_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the Atlas CO2 sensor + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Atlas CO2 sensor can report 2 values. #define ATLAS_CO2_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define ATLAS_CO2_INC_CALC_VARIABLES 0 +/**@}*/ + +/** + * @anchor sensor_atlas_co2_config + * @name Configuration Defines + * Defines to configure and set the address of the Atlas CO2 sensor + */ +/**@{*/ +/// @brief The default I2C address of the Atlas CO2 sensor is 0x69 (105) +#define ATLAS_CO2_I2C_ADDR 0x69 +/**@}*/ /** * @anchor sensor_atlas_co2_timing diff --git a/src/sensors/AtlasScientificDO.h b/src/sensors/AtlasScientificDO.h index 3cafe86c9..d9c40f23f 100644 --- a/src/sensors/AtlasScientificDO.h +++ b/src/sensors/AtlasScientificDO.h @@ -62,20 +62,31 @@ #include "VariableBase.h" #include "sensors/AtlasParent.h" -/** - * @brief Default I2C address is 0x61 (97) - */ -#define ATLAS_DO_I2C_ADDR 0x61 - /** @ingroup sensor_atlas_do */ /**@{*/ -// Sensor Specific Defines -/// @brief Sensor::_numReturnedValues; the Atlas DO sensor can report 2 values. +/** + * @anchor sensor_atlas_do_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the Atlas DO sensor + */ +/**@{*/ +/// @brief Sensor::_numReturnedValues; the Atlas EZO DO circuit can report 2 +/// values. #define ATLAS_DO_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define ATLAS_DO_INC_CALC_VARIABLES 0 +/**@}*/ +/** + * @anchor sensor_atlas_do_config + * @name Configuration Defines + * Defines to configure and set the address of the Atlas DO sensor + */ +/**@{*/ +/// @brief The default I2C address of the Atlas DO sensor is 0x61 (97) +#define ATLAS_DO_I2C_ADDR 0x61 +/**@}*/ /** * @anchor sensor_atlas_do_timing diff --git a/src/sensors/AtlasScientificEC.h b/src/sensors/AtlasScientificEC.h index 9908c810f..0bcb19001 100644 --- a/src/sensors/AtlasScientificEC.h +++ b/src/sensors/AtlasScientificEC.h @@ -70,13 +70,15 @@ #include "VariableBase.h" #include "sensors/AtlasParent.h" - -// Sensor Specific Defines /** @ingroup sensor_atlas_cond */ /**@{*/ -/// @brief Default I2C address is 0x64 (100) -#define ATLAS_COND_I2C_ADDR 0x64 +/** + * @anchor sensor_atlas_cond_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the Atlas conductivity sensor + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; Atlas EZO conductivity circuit can report /// 4 values. #define ATLAS_COND_NUM_VARIABLES 4 @@ -84,7 +86,19 @@ /// though we recommend users include a temperature sensor and calculate /// specific conductance in their own program. #define ATLAS_COND_INC_CALC_VARIABLES 0 +/**@}*/ +/** + * @anchor sensor_atlas_cond_config + * @name Configuration Defines + * Defines to configure and set the address of the Atlas conductivity + * sensor + */ +/**@{*/ +/// @brief The default I2C address of the Atlas conductivity sensor is 0x64 +/// (100) +#define ATLAS_COND_I2C_ADDR 0x64 +/**@}*/ /** * @anchor sensor_atlas_cond_timing diff --git a/src/sensors/AtlasScientificORP.h b/src/sensors/AtlasScientificORP.h index e722dfc38..260eed1ce 100644 --- a/src/sensors/AtlasScientificORP.h +++ b/src/sensors/AtlasScientificORP.h @@ -46,19 +46,31 @@ // Included Dependencies #include "sensors/AtlasParent.h" - -// Sensor Specific Defines /** @ingroup sensor_atlas_orp */ /**@{*/ -/// @brief Default I2C address is 0x62 (98) -#define ATLAS_ORP_I2C_ADDR 0x62 - +/** + * @anchor sensor_atlas_orp_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the Atlas ORP sensor + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Atlas EZO ORP circuit can report 1 /// value. #define ATLAS_ORP_NUM_VARIABLES 1 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define ATLAS_ORP_INC_CALC_VARIABLES 0 +/**@}*/ + +/** + * @anchor sensor_atlas_orp_config + * @name Configuration Defines + * Defines to configure and set the address of the Atlas ORP sensor + */ +/**@{*/ +/// @brief The default I2C address of the Atlas ORP sensor is 0x62 (98) +#define ATLAS_ORP_I2C_ADDR 0x62 +/**@}*/ /** * @anchor sensor_atlas_orp_timing diff --git a/src/sensors/AtlasScientificRTD.h b/src/sensors/AtlasScientificRTD.h index b9b20b066..c2793f0ca 100644 --- a/src/sensors/AtlasScientificRTD.h +++ b/src/sensors/AtlasScientificRTD.h @@ -51,23 +51,33 @@ // Included Dependencies #include "sensors/AtlasParent.h" - -/** - * @brief Default I2C address is 0x66 (102) - */ -#define ATLAS_RTD_I2C_ADDR 0x66 - -// Sensor Specific Defines /** @ingroup sensor_atlas_rtd */ /**@{*/ + /** - * @brief Sensor::_numReturnedValues; the Atlas EZO temperature circuit can - * report 1 value. + * @anchor sensor_atlas_rtd_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the Atlas RTD (temperature) + * sensor */ +/**@{*/ +/// @brief Sensor::_numReturnedValues; the Atlas EZO temperature circuit can +/// report 1 value. #define ATLAS_RTD_NUM_VARIABLES 1 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define ATLAS_RTD_INC_CALC_VARIABLES 0 +/**@}*/ +/** + * @anchor sensor_atlas_rtd_config + * @name Configuration Defines + * Defines to configure and set the address of the Atlas RTD (temperature) + * sensor + */ +/**@{*/ +/// @brief The default I2C address of the Atlas RTD sensor is 0x66 (102) +#define ATLAS_RTD_I2C_ADDR 0x66 +/**@}*/ /** * @anchor sensor_atlas_rtd_timing diff --git a/src/sensors/AtlasScientificpH.h b/src/sensors/AtlasScientificpH.h index c2d198445..017a4a7e7 100644 --- a/src/sensors/AtlasScientificpH.h +++ b/src/sensors/AtlasScientificpH.h @@ -48,18 +48,31 @@ // Included Dependencies #include "sensors/AtlasParent.h" - -// Sensor Specific Defines /** @ingroup sensor_atlas_ph */ /**@{*/ -/// @brief Default I2C address is 0x63 (99) -#define ATLAS_PH_I2C_ADDR 0x63 +/** + * @anchor sensor_atlas_ph_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the Atlas pH sensor + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Atlas EZO pH circuit can report 1 /// value. #define ATLAS_PH_NUM_VARIABLES 1 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define ATLAS_PH_INC_CALC_VARIABLES 0 +/**@}*/ + +/** + * @anchor sensor_atlas_ph_config + * @name Configuration Defines + * Defines to configure and set the address of the Atlas pH sensor + */ +/**@{*/ +/// @brief The default I2C address of the Atlas pH sensor is 0x63 (99) +#define ATLAS_PH_I2C_ADDR 0x63 +/**@}*/ /** * @anchor sensor_atlas_ph_timing diff --git a/src/sensors/BoschBME280.h b/src/sensors/BoschBME280.h index 6edd6ac26..ff7a4de98 100644 --- a/src/sensors/BoschBME280.h +++ b/src/sensors/BoschBME280.h @@ -105,12 +105,31 @@ /** @ingroup sensor_bme280 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_bme280_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the BME280 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the BME280 can report 4 values. #define BME280_NUM_VARIABLES 4 /// @brief Sensor::_incCalcValues; altitude is calculted within the Adafruit /// library. #define BME280_INC_CALC_VARIABLES 1 +/**@}*/ + +/** + * @anchor sensor_bme280_config + * @name Configuration Defines + * Defines to set the calibration of the calculated base pressure used to + * calculate altitude by the BME280. + */ +/**@{*/ +#ifndef SEALEVELPRESSURE_HPA || defined(DOXYGEN) +/// The atmospheric pressure at sea level +#define SEALEVELPRESSURE_HPA (1013.25) +#endif +/**@}*/ /** * @anchor sensor_bme280_timing @@ -243,11 +262,6 @@ #define BME280_ALTITUDE_DEFAULT_CODE "BoschBME280Altitude" /**@}*/ -/// The atmospheric pressure at sea level -#ifndef SEALEVELPRESSURE_HPA -#define SEALEVELPRESSURE_HPA (1013.25) -#endif - /* clang-format off */ /** * @brief The Sensor sub-class for the [Bosch BME280](@ref sensor_bme280). diff --git a/src/sensors/BoschBMP3xx.h b/src/sensors/BoschBMP3xx.h index 9f7899d61..292b76d09 100644 --- a/src/sensors/BoschBMP3xx.h +++ b/src/sensors/BoschBMP3xx.h @@ -149,12 +149,31 @@ /** @ingroup sensor_bmp3xx */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_bmp3xx_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by Bosch BMP3xx + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the BMP3xx can report 3 values. #define BMP3XX_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; altitude is calculted within the Adafruit /// library. #define BMP3XX_INC_CALC_VARIABLES 1 +/**@}*/ + +/** + * @anchor sensor_bme3xx_config + * @name Configuration Defines + * Defines to set the calibration of the calculated base pressure used to + * calculate altitude by the BME3xx. + */ +/**@{*/ +#ifndef SEALEVELPRESSURE_HPA || defined(DOXYGEN) +/// The atmospheric pressure at sea level +#define SEALEVELPRESSURE_HPA (1013.25) +#endif +/**@}*/ /** * @anchor sensor_bmp3xx_timing @@ -303,11 +322,6 @@ #define BMP3XX_ALTITUDE_DEFAULT_CODE "BoschBMP3xxAltitude" /**@}*/ -/// The atmospheric pressure at sea level -#ifndef SEALEVELPRESSURE_HPA -#define SEALEVELPRESSURE_HPA (1013.25) -#endif - /* clang-format off */ /** * @brief The Sensor sub-class for the [Bosch BMP3xx](@ref sensor_bmp3xx). diff --git a/src/sensors/CampbellClariVUE10.h b/src/sensors/CampbellClariVUE10.h index 3b6012221..ee9b8b865 100644 --- a/src/sensors/CampbellClariVUE10.h +++ b/src/sensors/CampbellClariVUE10.h @@ -67,13 +67,19 @@ /** @ingroup sensor_clarivue */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_clarivue_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the ClariVUE10 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the ClariVUE10 can report 7 values /// (although we only keep 3). #define CLARIVUE10_NUM_VARIABLES 7 /// @brief Sensor::_incCalcValues; The ClariVUE calculates averages and other /// stats on board, but we don't calculate any additional values. #define CLARIVUE10_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_clarivue_timing diff --git a/src/sensors/CampbellOBS3.h b/src/sensors/CampbellOBS3.h index 9a00969b7..d93af4c8d 100644 --- a/src/sensors/CampbellOBS3.h +++ b/src/sensors/CampbellOBS3.h @@ -82,9 +82,15 @@ #include "VariableBase.h" #include "SensorBase.h" -// Sensor Specific Defines /** @ingroup sensor_obs3 */ /**@{*/ + +/** + * @anchor sensor_obs3_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by OBS3 + */ +/**@{*/ /** * @brief Sensor::_numReturnedValues; the OBS3 can report 2 values. * @@ -97,6 +103,17 @@ /// @brief Sensor::_incCalcValues; turbidity is calculated from raw voltage /// using the input calibration equation. #define OBS3_INC_CALC_VARIABLES 1 +/**@}*/ + +/** + * @anchor sensor_obs3_config + * @name Configuration Defines + * Defines to help configure the address of the ADD used by the Campbell OBS3+ + */ +/**@{*/ +/// @brief The assumed address of the ADS1115, 1001 000 (ADDR = GND) +#define ADS1115_ADDRESS 0x48 +/**@}*/ /** * @anchor sensor_obs3_timing @@ -205,9 +222,6 @@ #endif /**@}*/ -/// @brief The assumed address of the ADS1115, 1001 000 (ADDR = GND) -#define ADS1115_ADDRESS 0x48 - /* clang-format off */ /** * @brief The Sensor sub-class for the diff --git a/src/sensors/CampbellRainVUE10.h b/src/sensors/CampbellRainVUE10.h index bbf8b938c..cbe552880 100644 --- a/src/sensors/CampbellRainVUE10.h +++ b/src/sensors/CampbellRainVUE10.h @@ -67,13 +67,19 @@ /** @ingroup sensor_rainvue */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_rainvue_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by RainVUE10 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the RainVUE10 can report 5 values /// (although we only keep 4). #define RAINVUE10_NUM_VARIABLES 5 /// @brief Sensor::_incCalcValues; The RainVUE calculates averages and other /// stats on board, but we don't calculate any additional values. #define RAINVUE10_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_rainvue_timing diff --git a/src/sensors/Decagon5TM.h b/src/sensors/Decagon5TM.h index fcee6d289..026345b6b 100644 --- a/src/sensors/Decagon5TM.h +++ b/src/sensors/Decagon5TM.h @@ -84,12 +84,18 @@ /** @ingroup sensor_fivetm */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_fivetm_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the Decagon 5TM + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the 5TM can report 3 values. #define TM_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; volumetric water content is calculated from /// the permittivity and the temperature. #define TM_INC_CALC_VARIABLES 1 +/**@}*/ /** * @anchor sensor_fivetm_timing diff --git a/src/sensors/DecagonCTD.h b/src/sensors/DecagonCTD.h index 59efae7d3..fd5a05623 100644 --- a/src/sensors/DecagonCTD.h +++ b/src/sensors/DecagonCTD.h @@ -69,11 +69,17 @@ /** @ingroup sensor_decagon_ctd */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_decagon_ctd_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by Decagon CTD + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the CTD can report 3 values. #define CTD_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define CTD_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_decagon_ctd_timing diff --git a/src/sensors/DecagonES2.h b/src/sensors/DecagonES2.h index 956847ebd..fb038d0d0 100644 --- a/src/sensors/DecagonES2.h +++ b/src/sensors/DecagonES2.h @@ -64,11 +64,17 @@ /** @ingroup sensor_es2 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_es2_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by Decagon ES2 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the ES2 can report 2 values. #define ES2_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define ES2_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_es2_timing diff --git a/src/sensors/EverlightALSPT19.h b/src/sensors/EverlightALSPT19.h index 53508dd45..1fe5ff834 100644 --- a/src/sensors/EverlightALSPT19.h +++ b/src/sensors/EverlightALSPT19.h @@ -63,13 +63,27 @@ /** @ingroup sensor_alspt19 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_alspt19_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by an ALS-PT19 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the ALS-PT19 can report 1 "raw" value /// (voltage) and we calculate current and illuminance from it. #define ALSPT19_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; we calculate photocurrent from the supply /// voltage and loading resistance and illuminance from the photocurrent. #define ALSPT19_INC_CALC_VARIABLES 2 +/**@}*/ + +/** + * @anchor sensor_alspt19_mayfly + * @name Pin Definitions for the Mayfly + * Specific pin definitions for the ALS-PT19 built in to the EnviroDIY Mayfly + * v1.x + */ +/**@{*/ /// @brief The power pin for the ALS on the EnviroDIY Mayfly v1.x #define MAYFLY_ALS_POWER_PIN -1 /// @brief The data pin for the ALS on the EnviroDIY Mayfly v1.x @@ -78,8 +92,16 @@ #define MAYFLY_ALS_SUPPLY_VOLTAGE 3.3 /// @brief The loading resistance for the ALS on the EnviroDIY Mayfly v1.x #define MAYFLY_ALS_LOADING_RESISTANCE 10 +/**@}*/ -#if !defined ALSPT19_ADC_RESOLUTION +/** + * @anchor sensor_alspt19_config + * @name Configuration Defines + * Defines to help configure the range and resolution of the ALS-PT119 depending + * on the processor and ADC in use. + */ +/**@{*/ +#if !defined ALSPT19_ADC_RESOLUTION || defined(DOXYGEN) /** * @brief Default resolution (in bits) of the voltage measurement * @@ -96,7 +118,7 @@ #define ALSPT19_ADC_RANGE (1 << ALSPT19_ADC_RESOLUTION) /* clang-format off */ -#if !defined ALSPT19_ADC_REFERENCE_MODE +#if !defined ALSPT19_ADC_REFERENCE_MODE || defined (DOXYGEN) #if defined (ARDUINO_ARCH_AVR) || defined (DOXYGEN) /** * @brief The voltage reference mode for the processor's ADC. @@ -144,6 +166,7 @@ #error The processor ADC reference type must be defined! #endif // ALSPT19_ADC_REFERENCE_MODE #endif // ARDUINO_ARCH_SAMD +/**@}*/ /* clang-format on */ /** diff --git a/src/sensors/FreescaleMPL115A2.h b/src/sensors/FreescaleMPL115A2.h index 1a27efdfc..08711308d 100644 --- a/src/sensors/FreescaleMPL115A2.h +++ b/src/sensors/FreescaleMPL115A2.h @@ -80,11 +80,17 @@ /** @ingroup sensor_mpl115a2 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_mpl115a2_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the MPL115A2 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the MPL115A2 can report 2 values. #define MPL115A2_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define MPL115A2_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_mpl115a2_timing diff --git a/src/sensors/GroPointGPLP8.h b/src/sensors/GroPointGPLP8.h index f6a4a97a1..3388bcad8 100644 --- a/src/sensors/GroPointGPLP8.h +++ b/src/sensors/GroPointGPLP8.h @@ -56,11 +56,17 @@ /** @ingroup sensor_gplp8 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_gplp8_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by GPLP8 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the GPLP8 can report 8 values. #define GPLP8_NUM_VARIABLES 21 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define GPLP8_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_gplp8_timing diff --git a/src/sensors/InSituRDO.h b/src/sensors/InSituRDO.h index 09e43ba9e..227b596f8 100644 --- a/src/sensors/InSituRDO.h +++ b/src/sensors/InSituRDO.h @@ -159,10 +159,15 @@ // Included Dependencies #include "sensors/SDI12Sensors.h" -// Sensor Specific Defines /** @ingroup sensor_insitu_rdo */ /**@{*/ +/** + * @anchor sensor_insitu_rdo_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the RDO PRO-X + */ +/**@{*/ /** * @brief Sensor::_numReturnedValues; the RDO PRO-X can report 4 values. * @@ -173,6 +178,7 @@ #define INSITU_RDO_NUM_VARIABLES 4 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define INSITU_RDO_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_insitu_rdo_timing diff --git a/src/sensors/InSituTrollSdi12a.h b/src/sensors/InSituTrollSdi12a.h index bd2368442..df585bd14 100644 --- a/src/sensors/InSituTrollSdi12a.h +++ b/src/sensors/InSituTrollSdi12a.h @@ -80,11 +80,20 @@ // Included Dependencies #include "sensors/SDI12Sensors.h" -// Sensor Specific Defines /** @ingroup sensor_insitu_troll */ /**@{*/ + +/** + * @anchor sensor_insitu_troll_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the TROLL 500 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the TROLL 500 can report 3 values. #define ITROLLA_NUM_VARIABLES 3 +/// @brief Sensor::_incCalcValues; we don't calculate any additional values. +#define ITROLLA_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_insitu_troll_timing diff --git a/src/sensors/KellerAcculevel.h b/src/sensors/KellerAcculevel.h index 08a99b472..080e7736a 100644 --- a/src/sensors/KellerAcculevel.h +++ b/src/sensors/KellerAcculevel.h @@ -54,7 +54,6 @@ // Included Dependencies #include "sensors/KellerParent.h" -// Sensor Specific Defines /** @ingroup sensor_acculevel */ /**@{*/ diff --git a/src/sensors/KellerNanolevel.h b/src/sensors/KellerNanolevel.h index 67c9a3782..9f7356e77 100644 --- a/src/sensors/KellerNanolevel.h +++ b/src/sensors/KellerNanolevel.h @@ -46,7 +46,6 @@ // Included Dependencies #include "sensors/KellerParent.h" -// Sensor Specific Defines /** @ingroup sensor_nanolevel */ /**@{*/ diff --git a/src/sensors/KellerParent.h b/src/sensors/KellerParent.h index 918d7b610..19bf79322 100644 --- a/src/sensors/KellerParent.h +++ b/src/sensors/KellerParent.h @@ -102,12 +102,18 @@ /** @ingroup keller_group */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor keller_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the RDO PRO-X + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Keller level sensors can report 3 /// values. #define KELLER_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define KELLER_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor keller_pressure diff --git a/src/sensors/MaxBotixSonar.h b/src/sensors/MaxBotixSonar.h index aec7c2aa2..987e53084 100644 --- a/src/sensors/MaxBotixSonar.h +++ b/src/sensors/MaxBotixSonar.h @@ -116,11 +116,17 @@ /** @ingroup sensor_maxbotix */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_maxbotix_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by Maxbotix sonar + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the HRXL can report 1 value. #define HRXL_NUM_VARIABLES 1 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define HRXL_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_maxbotix_timing diff --git a/src/sensors/MaximDS18.h b/src/sensors/MaximDS18.h index e5785f4c4..dbc94a643 100644 --- a/src/sensors/MaximDS18.h +++ b/src/sensors/MaximDS18.h @@ -99,11 +99,17 @@ /** @ingroup sensor_ds18 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_ds18_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the DS18 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the DS18 can report 1 value. #define DS18_NUM_VARIABLES 1 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define DS18_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_ds18_timing diff --git a/src/sensors/MaximDS3231.h b/src/sensors/MaximDS3231.h index 42f0f9b98..6532866f2 100644 --- a/src/sensors/MaximDS3231.h +++ b/src/sensors/MaximDS3231.h @@ -75,11 +75,17 @@ /** @ingroup sensor_ds3231 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_ds3231_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the DS3231 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the DS3231 can report 1 value. #define DS3231_NUM_VARIABLES 1 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define DS3231_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_ds3231_timing diff --git a/src/sensors/MeaSpecMS5803.h b/src/sensors/MeaSpecMS5803.h index f8c764685..3c5fbfee6 100644 --- a/src/sensors/MeaSpecMS5803.h +++ b/src/sensors/MeaSpecMS5803.h @@ -95,11 +95,17 @@ /** @ingroup sensor_ms5803 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_ms5803_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the MS5803 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the MS5803 can report 2 values. #define MS5803_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define MS5803_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_ms5803_timing diff --git a/src/sensors/MeterHydros21.h b/src/sensors/MeterHydros21.h index f66b8f926..709da4833 100644 --- a/src/sensors/MeterHydros21.h +++ b/src/sensors/MeterHydros21.h @@ -76,11 +76,17 @@ /** @ingroup sensor_hydros21 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_hydros21_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the Meter Hydros 21 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Hydros 21 can report 3 values. #define HYDROS21_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define HYDROS21_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_hydros21_timing diff --git a/src/sensors/MeterTeros11.h b/src/sensors/MeterTeros11.h index 6f8b92361..6d38253df 100644 --- a/src/sensors/MeterTeros11.h +++ b/src/sensors/MeterTeros11.h @@ -94,13 +94,19 @@ /** @ingroup sensor_teros11 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_teros11_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by Meter Teros 11 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Teros 11 can report 2 raw values - /// counts and temperature. #define TEROS11_NUM_VARIABLES 4 /// @brief Sensor::_incCalcValues; We calculate permittivity and water content /// from the raw counts and temperature reported by the Teros 11. #define TEROS11_INC_CALC_VARIABLES 2 +/**@}*/ /** * @anchor sensor_teros11_timing diff --git a/src/sensors/PaleoTerraRedox.h b/src/sensors/PaleoTerraRedox.h index 6419bf0cc..fbf6ece0f 100644 --- a/src/sensors/PaleoTerraRedox.h +++ b/src/sensors/PaleoTerraRedox.h @@ -82,12 +82,28 @@ /** @ingroup sensor_pt_redox */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_pt_redox_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by PaleoTerra redox sensor + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the PaleoTerra redox sensor can report 1 /// value. #define PTR_NUM_VARIABLES 1 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define PTR_INC_CALC_VARIABLES 0 +/**@}*/ + +/** + * @anchor sensor_pt_redox_config + * @name Configuration Defines + * Defines to set the address of the PaleoTerra redox sensor. + */ +/**@{*/ +/// @brief The default I2C address of the PaleoTerra redox sensor +#define MCP3421_ADR 0x68 +/**@}*/ /** * @anchor sensor_pt_redox_timing @@ -135,9 +151,6 @@ #define PTR_VOLTAGE_DEFAULT_CODE "PTRVoltage" /**@}*/ -/// @brief The default I2C address of the PaleoTerra redox sensor -#define MCP3421_ADR 0x68 - // The main class for the PaleoTerra Redox Sensor /* clang-format off */ /** diff --git a/src/sensors/ProcessorStats.h b/src/sensors/ProcessorStats.h index 38be597e7..1d8f68b12 100644 --- a/src/sensors/ProcessorStats.h +++ b/src/sensors/ProcessorStats.h @@ -72,12 +72,17 @@ /** @ingroup sensor_processor */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_processor_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the main processor + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the processor can report 3 values. #define PROCESSOR_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; sample number is (sort-of) calculated. #define PROCESSOR_INC_CALC_VARIABLES 1 - +/**@}*/ /** * @anchor sensor_processor_sensor_timing diff --git a/src/sensors/RainCounterI2C.h b/src/sensors/RainCounterI2C.h index 69034d88c..9e084bd12 100644 --- a/src/sensors/RainCounterI2C.h +++ b/src/sensors/RainCounterI2C.h @@ -92,13 +92,19 @@ /** @ingroup sensor_i2c_rain */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_i2c_rain_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the tipping bucket counter + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the tipping bucket counter can report 2 /// values. #define BUCKET_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we calculate rain depth from the number of /// tips, assuming either English or metric calibration. #define BUCKET_INC_CALC_VARIABLES 1 +/**@}*/ /** * @anchor sensor_i2c_rain_timing diff --git a/src/sensors/SensirionSHT4x.h b/src/sensors/SensirionSHT4x.h index 39e0e1e60..76548da38 100644 --- a/src/sensors/SensirionSHT4x.h +++ b/src/sensors/SensirionSHT4x.h @@ -82,11 +82,17 @@ /** @ingroup sensor_sht4x */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_sht4x_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the SHT4x + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the SHT4x can report 2 values. #define SHT4X_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define SHT4X_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_sht4x_timing diff --git a/src/sensors/TIADS1x15.h b/src/sensors/TIADS1x15.h index af75c6802..1253492b1 100644 --- a/src/sensors/TIADS1x15.h +++ b/src/sensors/TIADS1x15.h @@ -156,11 +156,27 @@ /** @ingroup sensor_ads1x15 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_ads1x15_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by ADS1x15 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the ADS1115 can report 1 value. #define TIADS1X15_NUM_VARIABLES 1 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define TIADS1X15_INC_CALC_VARIABLES 0 +/**@}*/ + +/** + * @anchor sensor_ads1x15_config + * @name Configuration Defines + * Defines to help configure the address of the ADD + */ +/**@{*/ +/// @brief The assumed address of the ADS1115, 1001 000 (ADDR = GND) +#define ADS1115_ADDRESS 0x48 +/**@}*/ /** * @anchor sensor_ads1x15_timing @@ -234,9 +250,6 @@ #endif /**@}*/ -/// @brief The assumed address of the ADS1115, 1001 000 (ADDR = GND) -#define ADS1115_ADDRESS 0x48 - /* clang-format off */ /** * @brief The Sensor sub-class for the diff --git a/src/sensors/TIINA219.h b/src/sensors/TIINA219.h index 0f0995030..f53609dc9 100644 --- a/src/sensors/TIINA219.h +++ b/src/sensors/TIINA219.h @@ -79,11 +79,27 @@ /** @ingroup sensor_ina219 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_ina219_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the INA219 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the INA219 can report 3 values. #define INA219_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define INA219_INC_CALC_VARIABLES 0 +/**@}*/ + +/** + * @anchor sensor_ina219_config + * @name Configuration Defines + * Defines to set the address of the INA219. + */ +/**@{*/ +/// @brief The default address of the INA219 +#define INA219_ADDRESS_BASE 0x40 +/**@}*/ /** * @anchor sensor_ina219_timing @@ -192,9 +208,6 @@ #define INA219_POWER_MW_DEFAULT_CODE "TIINA219Power" /**@}*/ -/// @brief The default address of the INA219 -#define INA219_ADDRESS_BASE 0x40 - /* clang-format off */ /** * @brief The Sensor sub-class for the diff --git a/src/sensors/TallyCounterI2C.h b/src/sensors/TallyCounterI2C.h index a42fd13f9..2a4f861c9 100644 --- a/src/sensors/TallyCounterI2C.h +++ b/src/sensors/TallyCounterI2C.h @@ -89,11 +89,27 @@ /** @ingroup sensor_tally */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_tally_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the Tally event counter + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Tally can report 1 value. #define TALLY_NUM_VARIABLES 1 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define TALLY_INC_CALC_VARIABLES 0 +/**@}*/ + +/** + * @anchor sensor_tally_config + * @name Configuration Defines + * Defines to set the address of the Tally event counter. + */ +/**@{*/ +/// @brief The default address of the Tally +#define TALLY_ADDRESS_BASE 0x33 +/**@}*/ /** * @anchor sensor_tally_timing @@ -140,9 +156,6 @@ #define TALLY_EVENTS_DEFAULT_CODE "TallyCounterI2CEvents" /**@}*/ -/// @brief The default address of the Tally -#define TALLY_ADDRESS_BASE 0x33 - /* clang-format off */ /** * @brief The Sensor sub-class for the diff --git a/src/sensors/TurnerCyclops.h b/src/sensors/TurnerCyclops.h index 0071dfb03..9ef9d6518 100644 --- a/src/sensors/TurnerCyclops.h +++ b/src/sensors/TurnerCyclops.h @@ -145,6 +145,13 @@ // Sensor Specific Defines /** @ingroup sensor_cyclops */ /**@{*/ + +/** + * @anchor sensor_cyclops_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by Cyclops + */ +/**@{*/ /** * @brief Sensor::_numReturnedValues; the Cyclops can report 2 values. * @@ -159,6 +166,17 @@ /// @brief Sensor::_incCalcValues; the raw voltage is reported, the other /// parameter is calculated using the input calibration equation. #define CYCLOPS_INC_CALC_VARIABLES 1 +/**@}*/ + +/** + * @anchor sensor_cyclops_config + * @name Configuration Defines + * Defines to help configure the address of the ADD used by the Cyclops + */ +/**@{*/ +/// @brief The assumed address of the ADS1115, 1001 000 (ADDR = GND) +#define ADS1115_ADDRESS 0x48 +/**@}*/ /** * @anchor sensor_cyclops_timing @@ -246,9 +264,6 @@ #endif /**@}*/ -/// @brief The assumed address of the ADS1115, 1001 000 (ADDR = GND) -#define ADS1115_ADDRESS 0x48 - /* clang-format off */ /** * @brief The Sensor sub-class for the diff --git a/src/sensors/VegaPuls21.h b/src/sensors/VegaPuls21.h index 815739b1b..9ea9ec732 100644 --- a/src/sensors/VegaPuls21.h +++ b/src/sensors/VegaPuls21.h @@ -61,11 +61,17 @@ /** @ingroup sensor_vega_puls21 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_vega_puls21_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by the VEGA PULS 21 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the VEGA PULS 21 can report 5 values #define VEGAPULS21_NUM_VARIABLES 5 /// @brief Sensor::_incCalcValues; #define VEGAPULS21_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_vega_puls21_timing diff --git a/src/sensors/YosemitechY4000.h b/src/sensors/YosemitechY4000.h index 400d61ddc..60a88c290 100644 --- a/src/sensors/YosemitechY4000.h +++ b/src/sensors/YosemitechY4000.h @@ -62,11 +62,17 @@ /** @ingroup sensor_y4000 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_y4000_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by a Yosemitch Y4000 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Y4000 can report 8 values. #define Y4000_NUM_VARIABLES 8 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define Y4000_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_y4000_timing diff --git a/src/sensors/YosemitechY504.h b/src/sensors/YosemitechY504.h index 2f5ff2019..f8d497c76 100644 --- a/src/sensors/YosemitechY504.h +++ b/src/sensors/YosemitechY504.h @@ -60,12 +60,18 @@ /** @ingroup sensor_y504 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_y504_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by a Yosemitech Y504 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Y504 can report 3 values. #define Y504_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; we calculated DO concentration from the /// percent saturation and the temperature. #define Y504_INC_CALC_VARIABLES 1 +/**@}*/ /** * @anchor sensor_y504_timing diff --git a/src/sensors/YosemitechY510.h b/src/sensors/YosemitechY510.h index c726f67d3..b876bfc23 100644 --- a/src/sensors/YosemitechY510.h +++ b/src/sensors/YosemitechY510.h @@ -56,11 +56,17 @@ /** @ingroup sensor_y510 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_y510_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by a Yosemitch Y510 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Y510 can report 2 values. #define Y510_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define Y510_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_y510_timing diff --git a/src/sensors/YosemitechY511.h b/src/sensors/YosemitechY511.h index e49ee49ae..9bfa4c89b 100644 --- a/src/sensors/YosemitechY511.h +++ b/src/sensors/YosemitechY511.h @@ -57,11 +57,17 @@ /** @ingroup sensor_y511 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_y511_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by a Yosemitch Y511 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Y511 can report 2 values. #define Y511_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define Y511_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_y511_timing diff --git a/src/sensors/YosemitechY514.h b/src/sensors/YosemitechY514.h index 138f44cea..5f8ec785d 100644 --- a/src/sensors/YosemitechY514.h +++ b/src/sensors/YosemitechY514.h @@ -58,11 +58,17 @@ /** @ingroup sensor_y514 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_y514_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by a Yosemitch Y514 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Y514 can report 2 values. #define Y514_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define Y514_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_y514_timing diff --git a/src/sensors/YosemitechY520.h b/src/sensors/YosemitechY520.h index 755db66e6..c1825f346 100644 --- a/src/sensors/YosemitechY520.h +++ b/src/sensors/YosemitechY520.h @@ -57,11 +57,17 @@ /** @ingroup sensor_y520 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_y520_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by a Yosemitch Y520 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Y520 can report 2 values. #define Y520_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define Y520_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_y520_timing diff --git a/src/sensors/YosemitechY532.h b/src/sensors/YosemitechY532.h index 3ca91bdec..d2ab9f406 100644 --- a/src/sensors/YosemitechY532.h +++ b/src/sensors/YosemitechY532.h @@ -57,11 +57,17 @@ /** @ingroup sensor_y532 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_y532_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by a Yosemitch Y532 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Y532 can report 3 values. #define Y532_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define Y532_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_y532_timing diff --git a/src/sensors/YosemitechY533.h b/src/sensors/YosemitechY533.h index 8e5e81627..661b6e2d2 100644 --- a/src/sensors/YosemitechY533.h +++ b/src/sensors/YosemitechY533.h @@ -56,11 +56,17 @@ /** @ingroup sensor_y533 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_y533_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by a Yosemitch Y533 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Y533 can report 2 values. #define Y533_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define Y533_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_y533_timing diff --git a/src/sensors/YosemitechY551.h b/src/sensors/YosemitechY551.h index 8cc2fbb13..dd2cc01b9 100644 --- a/src/sensors/YosemitechY551.h +++ b/src/sensors/YosemitechY551.h @@ -56,11 +56,17 @@ /** @ingroup sensor_y551 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_y551_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by a Yosemitch Y551 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Y551 can report 2 values. #define Y551_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define Y551_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_y551_timing diff --git a/src/sensors/YosemitechY560.h b/src/sensors/YosemitechY560.h index 31bb9227c..58067a951 100644 --- a/src/sensors/YosemitechY560.h +++ b/src/sensors/YosemitechY560.h @@ -57,11 +57,17 @@ /** @ingroup sensor_y560 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_y560_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by a Yosemitch Y560 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Y560 can report 3 values. #define Y560_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define Y560_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_y560_timing diff --git a/src/sensors/YosemitechY700.h b/src/sensors/YosemitechY700.h index f4923a472..82f722fe7 100644 --- a/src/sensors/YosemitechY700.h +++ b/src/sensors/YosemitechY700.h @@ -55,11 +55,17 @@ /** @ingroup sensor_y700 */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_y700_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by a Yosemitch Y700 + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the Y700 can report 2 values. #define Y700_NUM_VARIABLES 2 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define Y700_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_y700_timing diff --git a/src/sensors/ZebraTechDOpto.h b/src/sensors/ZebraTechDOpto.h index 26c4780d1..96e53dd44 100644 --- a/src/sensors/ZebraTechDOpto.h +++ b/src/sensors/ZebraTechDOpto.h @@ -59,16 +59,22 @@ /** @ingroup sensor_dopto */ /**@{*/ -// Sensor Specific Defines +/** + * @anchor sensor_dopto_var_counts + * @name Sensor Variable Counts + * The number of variables that can be returned by a ZebraTech D-Opto + */ +/**@{*/ /// @brief Sensor::_numReturnedValues; the D-Opto can report 3 values. #define DOPTO_NUM_VARIABLES 3 /// @brief Sensor::_incCalcValues; we don't calculate any additional values. #define DOPTO_INC_CALC_VARIABLES 0 +/**@}*/ /** * @anchor sensor_dopto_timing * @name Sensor Timing - * The sensor timing for an ZebraTech D-Opto + * The sensor timing for a ZebraTech D-Opto */ /**@{*/ /// @brief Sensor::_warmUpTime_ms; the D-Opto warms up in 275ms. Maximum @@ -100,7 +106,7 @@ /** * @anchor sensor_dopto_temp * @name Temperature - * The temperature variable from an ZebraTech D-Opto + * The temperature variable from a ZebraTech D-Opto * - Range is not specified in sensor datasheet * - Accuracy is ± 0.1°C * @@ -127,7 +133,7 @@ /** * @anchor sensor_dopto_dopercent * @name Dissolved Oxygen Percent Saturation - * The percent saturation variable from an ZebraTech D-Opto + * The percent saturation variable from a ZebraTech D-Opto * - Range is not specified in sensor datasheet * - Accuracy is 1 % of reading or 0.02PPM, whichever is greater * @@ -155,7 +161,7 @@ /** * @anchor sensor_dopto_domgl * @name Dissolved Oxygen Concentration - * The DO concentration variable from an ZebraTech D-Opto + * The DO concentration variable from a ZebraTech D-Opto * - Range is not specified in sensor datasheet * - Accuracy is 1 % of reading or 0.02PPM, whichever is greater * From 63caa413abadb1fa92dad2ec9a4300b42c23b352 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 14 Jun 2024 13:56:35 -0400 Subject: [PATCH 085/138] Remove cores from lib installer Signed-off-by: Sara Damiano --- .../install-deps-arduino-cli.sh | 27 ------------------- .../install-deps-platformio.sh | 25 ----------------- 2 files changed, 52 deletions(-) diff --git a/continuous_integration/install-deps-arduino-cli.sh b/continuous_integration/install-deps-arduino-cli.sh index 61ba26a4b..63370bcbf 100644 --- a/continuous_integration/install-deps-arduino-cli.sh +++ b/continuous_integration/install-deps-arduino-cli.sh @@ -9,33 +9,6 @@ set -e echo "\n\e[32mCurrent Arduino CLI version:\e[0m" arduino-cli version -echo "::group::Installing Platforms and Frameworks" -echo "\n\e[32mUpdating the core index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core update-index - -echo "\n\e[32mInstalling the Arduino AVR Core\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core install arduino:avr - -echo "\n\e[32mInstalling the EnviroDIY AVR Core\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core install EnviroDIY:avr - -echo "\n\e[32mInstalling the Arduino SAMD Core\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core install arduino:samd - -echo "\n\e[32mInstalling the Adafruit SAMD Core\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core install adafruit:samd - -echo "\n\e[32mUpdating the core index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core update-index - -echo "\n\e[32mUpgrading all cores\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core upgrade - -echo "\n\e[32mCurrently installed cores:\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core list -echo "::endgroup::" - - echo "::group::Installing Libraries" echo "\n\e[32mUpdating the library index\e[0m" arduino-cli --config-file continuous_integration/arduino_cli.yaml lib update-index diff --git a/continuous_integration/install-deps-platformio.sh b/continuous_integration/install-deps-platformio.sh index 22219218e..0dd8a6513 100644 --- a/continuous_integration/install-deps-platformio.sh +++ b/continuous_integration/install-deps-platformio.sh @@ -6,31 +6,6 @@ trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG # Exit with nonzero exit code if anything fails set -e -echo "::group::Installing Platforms and Frameworks" -echo "\e[32mInstalling Atmel AVR platforms \e[0m" -pio pkg install -g --platform atmelavr -pio pkg install -g --tool framework-arduino-avr -pio pkg install -g --tool tool-avrdude -pio pkg install -g --tool toolchain-atmelavr - -echo "\e[32mInstalling Atmel AVR framework \e[0m" -pio pkg install -g --platform atmelmegaavr -pio pkg install -g --tool framework-arduino-megaavr - -echo "\e[32mInstalling Atmel SAM platform \e[0m" -pio pkg install -g --platform atmelsam - -echo "\e[32mInstalling Atmel SAM framework \e[0m" -pio pkg install -g --tool framework-arduino-samd -pio pkg install -g --tool framework-arduino-samd-adafruit -pio pkg install -g --tool framework-arduino-samd-sodaq -pio pkg install -g --tool framework-cmsis -pio pkg install -g --tool framework-cmsis-atmel -pio pkg install -g --tool tool-bossac -pio pkg install -g --tool toolchain-gccarmnoneeabi -echo "::endgroup::" - - echo "::group::Installing Libraries" echo "\e[32m\nCurrently installed packages:\e[0m" pio pkg list -g -v From 3da4bc4efd17e24243fe711489116bad52abd1b5 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 14 Jun 2024 13:58:06 -0400 Subject: [PATCH 086/138] Rename library install shell files Signed-off-by: Sara Damiano --- ...stall-deps-arduino-cli.sh => install-libraries-arduino-cli.sh} | 0 ...install-deps-platformio.sh => install-libraries-platformio.sh} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename continuous_integration/{install-deps-arduino-cli.sh => install-libraries-arduino-cli.sh} (100%) rename continuous_integration/{install-deps-platformio.sh => install-libraries-platformio.sh} (100%) diff --git a/continuous_integration/install-deps-arduino-cli.sh b/continuous_integration/install-libraries-arduino-cli.sh similarity index 100% rename from continuous_integration/install-deps-arduino-cli.sh rename to continuous_integration/install-libraries-arduino-cli.sh diff --git a/continuous_integration/install-deps-platformio.sh b/continuous_integration/install-libraries-platformio.sh similarity index 100% rename from continuous_integration/install-deps-platformio.sh rename to continuous_integration/install-libraries-platformio.sh From 132453c8d5e9d49fad92e301fc2bca6c0645dd37 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 17 Jun 2024 18:05:43 -0400 Subject: [PATCH 087/138] Bump SensorModbusMaster Signed-off-by: Sara Damiano --- continuous_integration/dependencies.json | 2 +- library.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/continuous_integration/dependencies.json b/continuous_integration/dependencies.json index 9d1486adc..a6eae8fb3 100644 --- a/continuous_integration/dependencies.json +++ b/continuous_integration/dependencies.json @@ -242,7 +242,7 @@ "owner": "envirodiy", "library id": "1824", "url": "https://github.com/EnviroDIY/SensorModbusMaster", - "version": "~0.6.8", + "version": "~0.7.0", "note": "EnviroDIY SensorModbusMaster - Arduino library for communicating via modbus with the Arduino acting as the modbus master.", "authors": ["Sara Damiano"], "frameworks": "arduino", diff --git a/library.json b/library.json index d2d748692..f7aa743eb 100644 --- a/library.json +++ b/library.json @@ -303,7 +303,7 @@ "owner": "envirodiy", "library id": "1824", "url": "https://github.com/EnviroDIY/SensorModbusMaster", - "version": "~0.6.8", + "version": "~0.7.0", "note": "EnviroDIY SensorModbusMaster - Arduino library for communicating via modbus with the Arduino acting as the modbus master.", "authors": ["Sara Damiano"], "frameworks": "arduino", From 3a84fd92cfb0d7931dde4cdc7957449d619aae9c Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 17 Jun 2024 18:11:35 -0400 Subject: [PATCH 088/138] Move dir dox Signed-off-by: Sara Damiano --- docs/directories.dox | 10 ---------- docs/mcss-conf.py | 7 ++++++- examples/examples.dox | 33 +++++++++++++++++++++++++++++++++ extras/extras.dox | 5 +++++ 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/docs/directories.dox b/docs/directories.dox index 21f12bbbe..b5051b336 100644 --- a/docs/directories.dox +++ b/docs/directories.dox @@ -13,13 +13,3 @@ * * @brief Contains documentation for new users */ -/** - * @dir examples - * - * @brief Contains all of the example sketches - */ -/** - * @dir extras - * - * @brief Contains extra sketches for testing sensors and sub-libraries - */ diff --git a/docs/mcss-conf.py b/docs/mcss-conf.py index afad978a8..f3bd50575 100644 --- a/docs/mcss-conf.py +++ b/docs/mcss-conf.py @@ -164,7 +164,12 @@ "css/m-EnviroDIY+documentation.compiled.css", ] -EXTRA_FILES = ["gp-desktop-logo.png", "gp-mobile-logo.png", "gp-scrolling-logo.png"] +EXTRA_FILES = [ + "gp-desktop-logo.png", + "gp-mobile-logo.png", + "gp-scrolling-logo.png", + "clipboard.js", +] DESKTOP_LOGO = "gp-desktop-logo.png" MOBILE_LOGO = "gp-mobile-logo.png" SCROLLING_LOGO = "gp-scrolling-logo.png" diff --git a/examples/examples.dox b/examples/examples.dox index 864fcf6be..242a0e391 100644 --- a/examples/examples.dox +++ b/examples/examples.dox @@ -1,3 +1,8 @@ +/** + * @dir examples + * + * @brief Contains all of the example sketches. There is only one example in each subfolder - a standard for Arduino coding. + */ /** * @page page_the_examples * @m_innerpage{page_examples_basic} @@ -8,16 +13,22 @@ * @m_innerpage{example_learn_envirodiy} */ /** + * @dir single_sensor + * * @example{lineno} single_sensor.ino @m_examplenavigation{example_single_sensor,} @m_footernavigation * @brief An example using only sensor functions and no logging. * See [the walkthrough page](@ref example_single_sensor) for detailed instructions. */ /** + * @dir simple_logging + * * @example{lineno} simple_logging.ino @m_examplenavigation{example_simple_logging,} @m_footernavigation * @brief A simple data logging example. * See [the walkthrough page](@ref example_simple_logging) for detailed instructions. */ /** + * @dir simple_logging_LearnEnviroDIY + * * @example{lineno} simple_logging_LearnEnviroDIY.ino @m_examplenavigation{example_learn_envirodiy,} @m_footernavigation * @brief A data logging example for the Learn EnviroDIY tutorial. * See [the walkthrough page](@ref example_learn_envirodiy) for detailed instructions. @@ -33,11 +44,15 @@ * @m_innerpage{example_thingspeak} */ /** + * @dir logging_to_MMW + * * @example{lineno} logging_to_MMW.ino @m_examplenavigation{example_mmw,} @m_footernavigation * @brief Example logging data and publishing to Monitor My Watershed. * See [the walkthrough page](@ref example_mmw) for detailed instructions. */ /** + * @dir logging_to_ThingSpeak + * * @example{lineno} logging_to_ThingSpeak.ino @m_examplenavigation{example_thingspeak,} @m_footernavigation * @brief Example logging data and publishing to ThingSpeak. * See [the walkthrough page](@ref example_thingspeak) for detailed instructions. @@ -54,16 +69,22 @@ * @m_innerpage{example_data_saving} */ /** + * @dir baro_rho_correction + * * @example{lineno} baro_rho_correction.ino @m_examplenavigation{example_baro_rho,} @m_footernavigation * @brief Example demonstrating calculated variables. * See [the walkthrough page](@ref example_baro_rho) for detailed instructions. */ /** + * @dir double_logger + * * @example{lineno} double_logger.ino @m_examplenavigation{example_double_log,} @m_footernavigation * @brief Example logging at two different timing intervals * See [the walkthrough page](@ref example_double_log) for detailed instructions. */ /** + * @dir data_saving + * * @example{lineno} data_saving.ino @m_examplenavigation{example_data_saving,} @m_footernavigation * @brief Example publishing only a portion of the logged variables. * See [the walkthrough page](@ref example_data_saving) for detailed instructions. @@ -82,26 +103,36 @@ * @m_innerpage{example_drwi_no_cell} */ /** + * @dir DRWI_Mayfly1 + * * @example{lineno} DRWI_Mayfly1.ino @m_examplenavigation{example_drwi_mayfly1,} @m_footernavigation * @brief Example for DRWI CitSci LTE sites with a Mayfly 1.x utilizing on-board sensors. * See [the walkthrough page](@ref example_drwi_mayfly1) for detailed instructions. */ /** + * @dir DRWI_SIM7080LTE + * * @example{lineno} DRWI_SIM7080LTE.ino @m_examplenavigation{example_drwi_ediylte,} @m_footernavigation * @brief Example for DRWI CitSci LTE sites. * See [the walkthrough page](@ref example_drwi_ediylte) for detailed instructions. */ /** + * @dir DRWI_DigiLTE + * * @example{lineno} DRWI_DigiLTE.ino @m_examplenavigation{example_drwi_digilte,} @m_footernavigation * @brief Example for DRWI CitSci LTE sites. * See [the walkthrough page](@ref example_drwi_digilte) for detailed instructions. */ /** + * @dir DRWI_2G + * * @example{lineno} DRWI_2G.ino @m_examplenavigation{example_drwi_2g,} @m_footernavigation * @brief Example for DRWI CitSci 2G sites. * See [the walkthrough page](@ref example_drwi_2g) for detailed instructions. */ /** + * @dir DRWI_NoCellular + * * @example{lineno} DRWI_NoCellular.ino @m_examplenavigation{example_drwi_no_cell,} @m_footernavigation * @brief Example for DRWI CitSci without cellular service. * See [the walkthrough page](@ref example_drwi_no_cell) for detailed instructions. @@ -116,6 +147,8 @@ * @m_innerpage{example_menu} */ /** + * @dir menu_a_la_carte + * * @example{lineno} menu_a_la_carte.ino @m_examplenavigation{example_menu,} @m_footernavigation * @brief Example with all possible functionality. * See [the walkthrough page](@ref example_menu) for detailed instructions. diff --git a/extras/extras.dox b/extras/extras.dox index 5f2184672..ec820a376 100644 --- a/extras/extras.dox +++ b/extras/extras.dox @@ -1,3 +1,8 @@ +/** + * @dir extras + * + * @brief Contains extra sketches for testing and configuring new sensors. + */ /** * @example{lineno} powerOn.ino * @brief Testing sketch that simply turns on power to the sensors on the Mayfly. From 427529cf6f4e8d6e106cb532d4a1f370b32faa7c Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 17 Jun 2024 19:18:12 -0400 Subject: [PATCH 089/138] Typo fix, inner page Signed-off-by: Sara Damiano --- docs/mcss-conf.py | 3 ++- examples/DRWI_Mayfly1/ReadMe.md | 4 ++-- examples/DRWI_Mayfly1_WiFi/ReadMe.md | 4 ++-- examples/examples.dox | 1 + 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/mcss-conf.py b/docs/mcss-conf.py index f3bd50575..f15b3a6d7 100644 --- a/docs/mcss-conf.py +++ b/docs/mcss-conf.py @@ -104,7 +104,8 @@ ( "Examples", "page_the_examples", - [("Other Helper Sketches", "page_extra_helper_sketches")], + [], + # [("Other Helper Sketches", "page_extra_helper_sketches")], # [ # ( # "Basic Functionality", diff --git a/examples/DRWI_Mayfly1/ReadMe.md b/examples/DRWI_Mayfly1/ReadMe.md index 65f633b27..b026248df 100644 --- a/examples/DRWI_Mayfly1/ReadMe.md +++ b/examples/DRWI_Mayfly1/ReadMe.md @@ -1,4 +1,4 @@ -# DRWI Sites with a Mayfly 1.x and EnviroDIY LTE Bees +# DRWI Sites with a Mayfly 1.x and EnviroDIY LTE Bee Example sketch for using the EnviroDIY SIM7080G LTE cellular module with an EnviroDIY Mayfly Data Logger. @@ -28,7 +28,7 @@ _______ [//]: # ( Start GitHub Only ) -- [DRWI Sites with a Mayfly 1.x and EnviroDIY LTE Bees](#drwi-sites-with-a-mayfly-1x-and-envirodiy-lte-bees) +- [DRWI Sites with a Mayfly 1.x and EnviroDIY LTE Bee](#drwi-sites-with-a-mayfly-1x-and-envirodiy-lte-bee) - [Unique Features of the DRWI Mayfly 1.x LTE Example](#unique-features-of-the-drwi-mayfly-1x-lte-example) [//]: # ( End GitHub Only ) diff --git a/examples/DRWI_Mayfly1_WiFi/ReadMe.md b/examples/DRWI_Mayfly1_WiFi/ReadMe.md index 6682830ae..4ed62c5a6 100644 --- a/examples/DRWI_Mayfly1_WiFi/ReadMe.md +++ b/examples/DRWI_Mayfly1_WiFi/ReadMe.md @@ -1,4 +1,4 @@ -# DRWI Sites with a Mayfly 1.x and EnviroDIY ESP32 WiFi Bees +# DRWI Sites with a Mayfly 1.x and EnviroDIY ESP32 WiFi Bee Example sketch for using the EnviroDIY ESP32 WiFi cellular module with an EnviroDIY Mayfly Data Logger. @@ -24,7 +24,7 @@ _______ [//]: # ( Start GitHub Only ) -- [DRWI Sites with a Mayfly 1.x and EnviroDIY ESP32 WiFi Bees](#drwi-sites-with-a-mayfly-1x-and-envirodiy-esp32-wifi-bees) +- [DRWI Sites with a Mayfly 1.x and EnviroDIY ESP32 WiFi Bee](#drwi-sites-with-a-mayfly-1x-and-envirodiy-esp32-wifi-bee) - [Unique Features of the DRWI Mayfly 1.x WiFi Example](#unique-features-of-the-drwi-mayfly-1x-wifi-example) [//]: # ( End GitHub Only ) diff --git a/examples/examples.dox b/examples/examples.dox index 242a0e391..8c2e28ee9 100644 --- a/examples/examples.dox +++ b/examples/examples.dox @@ -97,6 +97,7 @@ * @page page_examples_drwi DRWI Citizen Science * [DRWI Citizen Science](@ref examples_drwi) * @m_innerpage{example_drwi_mayfly1} + * @m_innerpage{example_drwi_mayfly1_wifi} * @m_innerpage{example_drwi_ediylte} * @m_innerpage{example_drwi_digilte} * @m_innerpage{example_drwi_2g} From 860b56ab47969da6ca4b316664c0ed74f80ed895 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:42:53 +0000 Subject: [PATCH 090/138] ci: bump softprops/action-gh-release from 2.0.5 to 2.0.6 Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.0.5 to 2.0.6. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/v2.0.5...v2.0.6) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/prepare_release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prepare_release.yaml b/.github/workflows/prepare_release.yaml index 07f3fabe8..db9322a0d 100644 --- a/.github/workflows/prepare_release.yaml +++ b/.github/workflows/prepare_release.yaml @@ -151,7 +151,7 @@ jobs: # Create a new release - name: Create release id: create_release - uses: softprops/action-gh-release@v2.0.5 + uses: softprops/action-gh-release@v2.0.6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 110ca9b37cc5105d753d174d8235f7979715296d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:07:58 +0000 Subject: [PATCH 091/138] ci: bump arduino/setup-arduino-cli from 1.1.2 to 2.0.0 Bumps [arduino/setup-arduino-cli](https://github.com/arduino/setup-arduino-cli) from 1.1.2 to 2.0.0. - [Release notes](https://github.com/arduino/setup-arduino-cli/releases) - [Commits](https://github.com/arduino/setup-arduino-cli/compare/v1.1.2...v2.0.0) --- updated-dependencies: - dependency-name: arduino/setup-arduino-cli dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build_examples.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_examples.yaml b/.github/workflows/build_examples.yaml index bfdc620ee..3d000ae43 100644 --- a/.github/workflows/build_examples.yaml +++ b/.github/workflows/build_examples.yaml @@ -123,7 +123,7 @@ jobs: # We use the `arduino/setup-arduino-cli` action to install and # configure the Arduino CLI on the system. - name: Setup Arduino CLI - uses: arduino/setup-arduino-cli@v1.1.2 + uses: arduino/setup-arduino-cli@v2.0.0 - name: Restore Arduino platforms and libraries uses: actions/cache@v4 From a5ba55c3479a78c5c91a90690fcf0b27af72053a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jul 2024 17:35:45 +0000 Subject: [PATCH 092/138] ci: bump softprops/action-gh-release from 2.0.6 to 2.0.8 Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.0.6 to 2.0.8. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/v2.0.6...v2.0.8) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/prepare_release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prepare_release.yaml b/.github/workflows/prepare_release.yaml index db9322a0d..47eba14bb 100644 --- a/.github/workflows/prepare_release.yaml +++ b/.github/workflows/prepare_release.yaml @@ -151,7 +151,7 @@ jobs: # Create a new release - name: Create release id: create_release - uses: softprops/action-gh-release@v2.0.6 + uses: softprops/action-gh-release@v2.0.8 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 542d32153657c7377170ced0c813da9acb9f563d Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 7 Aug 2024 09:04:16 -0400 Subject: [PATCH 093/138] track pio scripts Signed-off-by: Sara Damiano --- pioScripts/generate_compile_commands.py | 2 +- pioScripts/install_shared_deps.py | 218 ++++++++++++++ pioScripts/install_working_dependencies.py | 322 +++++++++++++++++++++ pioScripts/target_pio_versions.py | 15 + 4 files changed, 556 insertions(+), 1 deletion(-) create mode 100644 pioScripts/install_shared_deps.py create mode 100644 pioScripts/install_working_dependencies.py create mode 100644 pioScripts/target_pio_versions.py diff --git a/pioScripts/generate_compile_commands.py b/pioScripts/generate_compile_commands.py index afec170ef..8629e5a1a 100644 --- a/pioScripts/generate_compile_commands.py +++ b/pioScripts/generate_compile_commands.py @@ -3,7 +3,7 @@ Import("env") -if "compiledb" not in COMMAND_LINE_TARGETS: +if "compiledb" in COMMAND_LINE_TARGETS: print("Generating compile commands!") # include toolchain paths diff --git a/pioScripts/install_shared_deps.py b/pioScripts/install_shared_deps.py new file mode 100644 index 000000000..00aed2b13 --- /dev/null +++ b/pioScripts/install_shared_deps.py @@ -0,0 +1,218 @@ +from SCons.Script import ( + ARGUMENTS, + BUILD_TARGETS, + COMMAND_LINE_TARGETS, + AlwaysBuild, + Builder, + Default, + DefaultEnvironment, +) +import subprocess +from os import makedirs +from os.path import isdir +import re + +Import("env") + +if "idedata" in COMMAND_LINE_TARGETS: + env.Exit(0) + +if env.IsCleanTarget(): + print("==== WE WANT TO DO A CLEAN ====") + +if env.IsIntegrationDump(): + print("==== INTEGRATION DUMP ====") + +# print("Working on environment (PIOENV) {}".format(env["PIOENV"])) +# print( +# "Project workspace directory (PROJECT_WORKSPACE_DIR): {}".format( +# env["PROJECT_WORKSPACE_DIR"] +# ) +# ) +# print("Project source directory (PROJECT_SRC_DIR): {}".format(env["PROJECT_SRC_DIR"])) +# print( +# "Project build directory (PROJECT_BUILD_DIR): {}".format(env["PROJECT_BUILD_DIR"]) +# ) +# print("Enviroment build directory: {}".format(env["BUILD_DIR"])) +# print("Project lib deps directory: {}".format(env["PROJECT_LIBDEPS_DIR"])) +# print("Enviroment lib path: {}".format(env["LIBPATH"])) +# print("Enviroment lib source directories: {}".format(env["LIBSOURCE_DIRS"])) + +print("\nInstalling and updating common libraries") + + +def get_shared_lib_dir(env): + # Get shared_lib_dir + return env.GetProjectOption("custom_shared_lib_dir") + + +def get_shared_lib_deps(env): + # Get lib_deps + config = env.GetProjectConfig() + raw_lib_deps = env.GetProjectOption("custom_shared_lib_deps") + lib_deps = config.parse_multi_values(raw_lib_deps) + return lib_deps + + +def get_ignored_lib_deps(env): + # Get lib_deps + config = env.GetProjectConfig() + raw_lib_ignore = env.GetProjectOption("lib_ignore") + lib_ignore = config.parse_multi_values(raw_lib_ignore) + return lib_ignore + + +pio_pkg_command = [env.subst("$PYTHONEXE"), "-m", "platformio", "pkg"] + + +def install_shared_dependencies(env, verbose): + # Add verbose text + if int(verbose) >= 1: + print("Installing to {}".format(get_shared_lib_dir(env))) + + # Create shared_lib_dirif it does not exist + if not isdir(get_shared_lib_dir(env)): + if int(verbose) >= 1: + print( + "Directory {} doesn't exist, creating it".format( + get_shared_lib_dir(env) + ) + ) + makedirs(get_shared_lib_dir(env)) + + # Build dependency installation command + install_cmd = pio_pkg_command + ["install"] + install_cmd.extend(["--storage-dir", get_shared_lib_dir(env)]) + + # # Add verbose to command + # if int(verbose) < 1: + # install_cmd.append("-s") + + # Add dependencies to command + for lib in get_shared_lib_deps(env): + install_cmd.append("-l") + install_cmd.append(lib) + + # Run command + # print(install_cmd) + install_result = subprocess.run( + install_cmd, capture_output=True, text=True, check=True + ) + print(install_result.stdout) + print(install_result.stderr) + + +def update_shared_dependencies(env, verbose): + # Build dependency update command + update_cmd = pio_pkg_command + ["update", "-g"] + + # Add verbose to command + if int(verbose) < 1: + update_cmd.append("-s") + + # set the storage directory for the libraries + update_cmd.extend(["--storage-dir", get_shared_lib_dir(env)]) + + # Add dependencies to command + for lib in get_shared_lib_deps(env): + update_cmd.append("-l") + update_cmd.append(lib) + + # Run update command + print("Updating libraries") + # print(update_cmd) + update_result = subprocess.run( + update_cmd, capture_output=True, text=True, check=True + ) + print(update_result.stdout) + print(update_result.stderr) + + +def parse_global_installs(env, verbose): + # Build dependency list command + # pio pkg list -v -g --only-libraries --storage-dir "C:\Users\sdamiano\Documents\GitHub\EnviroDIY\ModularSensors\.pio\libdeps\shared" + list_cmd = pio_pkg_command + [ + "list", + "-g", + "--only-libraries", + ] + + # Add verbose to command + if int(verbose) >= 1: + list_cmd.append("-v") + + # set the storage directory for the libraries + list_cmd.extend(["--storage-dir", get_shared_lib_dir(env)]) + + # Run update command + print("Listing libraries") + # print(list_cmd) + list_result = subprocess.run(list_cmd, capture_output=True, text=True, check=True) + # print(list_result.stdout) + # print(list_result.stderr) + + lib_list_presort = [] + + for line in list_result.stdout.split("\n"): + if int(verbose) >= 1: + print(line) + # print(line.split()) + match = re.search( + r".*? (?P[\w\s-]*?) @ (?P[\w\s\.\+-]*?) \(required: (?:git\+)?(?P.*?)(?: @ .*?)?, (?P.*?)\)", + line, + ) + if match: + if int(verbose) >= 1: + print("Library name: {}".format(match.group("lib_name"))) + print("Library Version: {}".format(match.group("lib_version"))) + print("Library Req: {}".format(match.group("lib_req"))) + print("Library Storage Dir: {}".format(match.group("lib_dir"))) + shared_entry = list( + filter( + lambda x: match.group("lib_req").lower() in x.lower(), + get_shared_lib_deps(env), + ) + ) + is_in_shared = len(shared_entry) > 0 + if is_in_shared: + shared_position = get_shared_lib_deps(env).index(shared_entry[0]) + else: + shared_position = -1 + is_ignored = match.group("lib_name") in get_ignored_lib_deps(env) + match_groups = match.groupdict() + match_groups["shared_entry"] = shared_entry + match_groups["is_in_shared"] = is_in_shared + match_groups["is_ignored"] = is_ignored + match_groups["shared_position"] = shared_position + lib_list_presort.append(match_groups) + else: + if int(verbose) >= 1: + print("XXXXXXXXXXXXXXXXXXXXXXX NO MATCH XXXXXXXXXXXXXXXXXXXXXXX") + if int(verbose) >= 1: + print("##########") + + lib_list = sorted(lib_list_presort, key=lambda d: d["shared_position"]) + if int(verbose) >= 1: + print(lib_list) + + lib_used = [] + for lib in lib_list: + if not lib["is_ignored"]: + lib_used.append(f"{lib['lib_name']}=symlink://{lib['lib_dir']}") + if int(verbose) >= 1: + print(lib_used) + + platform = env.PioPlatform() + prev_lib_deps = env.GetProjectOption("lib_deps") + new_lib_deps = prev_lib_deps + lib_used + env_section = "env:" + env["PIOENV"] + platform.config.set(env_section, "lib_deps", new_lib_deps) + + +# Get verbose level +VERBOSE = ARGUMENTS.get("PIOVERBOSE", 0) + +# Intall dependencies listed in env shared_lib_deps to shared_lib_dir +install_shared_dependencies(env, VERBOSE) +update_shared_dependencies(env, VERBOSE) +parse_global_installs(env, VERBOSE) diff --git a/pioScripts/install_working_dependencies.py b/pioScripts/install_working_dependencies.py new file mode 100644 index 000000000..8c75bb4da --- /dev/null +++ b/pioScripts/install_working_dependencies.py @@ -0,0 +1,322 @@ +# %% +import copy +import os +import sys +from typing import Union +from SCons.Script import ( + ARGUMENTS, + BUILD_TARGETS, + COMMAND_LINE_TARGETS, + AlwaysBuild, + Builder, + Default, + DefaultEnvironment, +) +import subprocess +from os import makedirs +from os.path import isdir +import re +import json + +from platformio.project.config import ProjectConfig + +# from platformio.package.meta import PackageSpec + + +# %% +Import("env") +print("Working on environment (PIOENV) {}".format(env["PIOENV"])) +print("Enviroment and project settings:") +for project_directory in [ + "PROJECT_DIR", + "PROJECT_CORE_DIR", + "PROJECT_PACKAGES_DIR", + "PROJECT_WORKSPACE_DIR", + "PROJECT_INCLUDE_DIR", + "PROJECT_SRC_DIR", + "PROJECT_TEST_DIR", + "PROJECT_DATA_DIR", + "PROJECT_BUILD_DIR", + "PROJECT_LIBDEPS_DIR", + "LIBSOURCE_DIRS", + "LIBPATH", + "PIOENV", + "BUILD_DIR", + "BUILD_TYPE", + "BUILD_CACHE_DIR", + "LINKFLAGS", +]: + print(f"{project_directory}: {env[project_directory]}") + + +shared_lib_dir = env["LIBSOURCE_DIRS"][0] +shared_lib_abbr = ".pio/libdeps/shared" +project_ini_file = f"{env['PROJECT_DIR']}\\platformio.ini" +library_json_file = f"{env['PROJECT_DIR']}\\library.json" +examples_deps_file = f"{env['PROJECT_DIR']}\\examples\\example_dependencies.json" + +proj_config = ProjectConfig(path=project_ini_file) +envs = proj_config.envs() + + +# %% +# find dependencies in the platformio.ini file +def get_shared_lib_deps(env): + # Get lib_deps + config = env.GetProjectConfig() + raw_lib_deps = env.GetProjectOption("custom_shared_lib_deps", "") + lib_deps = config.parse_multi_values(raw_lib_deps) + return lib_deps + # convert to dict, taking advantage of PlatformIO's PackageSpec parser + # lib_deps = [] + # for raw_lib_dep in raw_lib_deps: + # spec = PackageSpec(raw_lib_dep) + # dep_dict = {} + # if spec.owner is not None: + # dep_dict["owner"] = spec.owner + # if spec.name is not None: + # dep_dict["name"] = spec.name + # if spec.uri is not None: + # dep_dict["version"] = spec.uri + # elif spec.requirements is not None: + # dep_dict["version"] = spec.requirements + # lib_deps.append(copy.deepcopy(dep_dict)) + # return lib_deps + + +def get_ignored_lib_deps(env): + return proj_config.get(section=f"env:{env}", option="lib_ignore") + + +# find dependencies based on the library specification +if os.path.isfile(os.path.join(env["PROJECT_DIR"], "library.json")): + with open(os.path.join(env["PROJECT_DIR"], "library.json")) as f: + library_specs = json.load(f) +else: + library_specs = {"dependencies": []} +# find dependencies based on the examples +if os.path.isfile( + os.path.join(env["PROJECT_DIR"], "examples/example_dependencies.json") +): + with open( + os.path.join(env["PROJECT_DIR"], "examples/example_dependencies.json") + ) as f: + example_specs = json.load(f) +else: + example_specs = {"dependencies": []} + +dependencies = get_shared_lib_deps(env) +if "dependencies" in library_specs.keys(): + dependencies.extend(library_specs["dependencies"]) +if "dependencies" in example_specs.keys(): + dependencies.extend(example_specs["dependencies"]) + +# quit if there are no dependencies +if len(dependencies) == 0: + print("No dependencies to install!") + sys.exit() + +# %% +print(f"\nInstalling and updating common libraries in {shared_lib_dir}") + +# Create shared_lib_dir if it does not exist +if not isdir(shared_lib_dir): + makedirs(shared_lib_dir) + + +def create_pio_ci_command( + library: Union[dict | str], + update: bool = True, + include_version: bool = True, +) -> list: + pio_command_args = [ + "pio", + "pkg", + "update" if update else "install", + "--skip-dependencies", + "-g", + "--storage-dir", + shared_lib_dir, + "--library", + ] + if isinstance(library, str): + pio_command_args.append(library) + return pio_command_args + + if "owner" in library.keys() and "github" in library["version"]: + pio_command_args.append(library["version"]) + elif ( + "owner" in library.keys() + and "name" in library.keys() + and "version" in library.keys() + ): + lib_dep = f"{library['owner']}/{library['name']}" + if include_version: + lib_dep += f"@{library['version']}" + pio_command_args.append(lib_dep) + elif "name" in library.keys() and "version" in library.keys(): + lib_dep = f"{library['name']}" + if include_version: + lib_dep += f"@{library['version']}" + pio_command_args.append(lib_dep) + else: + pio_command_args.append(library["name"]) + return pio_command_args + + +deps_to_install = [] + + +# %% +def install_shared_dependencies(verbose): + if verbose: + print("\nInstalling libraries") + + for lib in dependencies: + lib_install_cmd = create_pio_ci_command( + library=lib, update=False, include_version=True + ) + deps_to_install.extend(lib_install_cmd[-1]) + + # Run command + print(lib_install_cmd) + if verbose: + print(f"Installing {lib}") + install_result = subprocess.run( + lib_install_cmd, capture_output=True, text=True, check=True + ) + print(install_result.stdout) + # print(install_result.stderr) + + +install_shared_dependencies(True) + + +# %% +def update_shared_dependencies(verbose): + if verbose: + print("\nUpdating libraries") + + for lib in dependencies: + lib_update_cmd = create_pio_ci_command( + library=lib, update=True, include_version=False + ) + + # Run update command + print(lib_update_cmd) + if verbose: + print(f"Updating {lib}") + update_result = subprocess.run( + lib_update_cmd, capture_output=True, text=True, check=True + ) + print(update_result.stdout) + # print(update_result.stderr) + + +update_shared_dependencies(True) + + +# %% +def parse_global_installs(verbose: bool = False): + # Build dependency list command + # pio pkg list -v -g --only-libraries --storage-dir "C:\Users\sdamiano\Documents\GitHub\EnviroDIY\ModularSensors\.pio\libdeps\shared" + list_cmd = ["pio", "pkg", "list", "-g", "--only-libraries", "-v"] + + # set the storage directory for the libraries + list_cmd.extend(["--storage-dir", shared_lib_dir]) + + # Run update command + # print("Listing libraries") + # print(list_cmd) + list_result = subprocess.run(list_cmd, capture_output=True, text=True, check=True) + # print(list_result.stdout) + # print(list_result.stderr) + + lib_list_presort = [] + + for line in list_result.stdout.split("\n"): + if int(verbose) >= 1: + print(line) + # print(line.split()) + match = re.search( + r".*? (?P[\w\s-]*?) @ (?P[\w\s\.\+-]*?) \(required: (?:git\+)?(?P.*?)(?: @ .*?)?, (?P.*?)\)", + line, + ) + if match: + if int(verbose) >= 1: + print("Library name: {}".format(match.group("lib_name"))) + print("Library Version: {}".format(match.group("lib_version"))) + print("Library Req: {}".format(match.group("lib_req"))) + print("Library Storage Dir: {}".format(match.group("lib_dir"))) + shared_entry = list( + filter( + lambda x: match.group("lib_req").lower() in x.lower(), + deps_to_install, + ) + ) + is_in_shared = len(shared_entry) > 0 + if is_in_shared: + shared_position = deps_to_install.index(shared_entry[0]) + else: + shared_position = -1 + if match.group("lib_name") == "Adafruit BusIO": + shared_position = -2 + match_groups = match.groupdict() + match_groups["shared_entry"] = shared_entry + match_groups["is_in_shared"] = is_in_shared + match_groups["shared_position"] = shared_position + lib_list_presort.append(match_groups) + else: + if int(verbose) >= 1: + print("XXXXXXXXXXXXXXXXXXXXXXX NO MATCH XXXXXXXXXXXXXXXXXXXXXXX") + if int(verbose) >= 1: + print("##########") + + lib_list = sorted(lib_list_presort, key=lambda d: d["shared_position"]) + if int(verbose) >= 1: + print(lib_list) + return lib_list + + +lib_list = parse_global_installs(False) + + +# %% +def create_symlink_list(environment: str, verbose: bool = False): + lib_symlinks = [] + ign_symlinks = [] + print("Creating symlink list") + for lib in lib_list: + is_ignored = lib["lib_name"] in get_ignored_lib_deps(environment) + if not is_ignored or lib["lib_name"] in [ + "Adafruit GFX Library", + "Adafruit SSD1306", + ]: + lib_symlinks.append( + f"{lib['lib_name']}=symlink://{lib['lib_dir']}".replace( + shared_lib_dir, shared_lib_abbr + ) + .replace("\\\\", "/") + .replace("\\", "/") + ) + else: + ign_symlinks.append( + f"{lib['lib_name']}=symlink://{lib['lib_dir']}".replace( + shared_lib_dir, shared_lib_abbr + ) + .replace("\\\\", "/") + .replace("\\", "/") + ) + if int(verbose) >= 1: + print(lib_symlinks) + + return lib_symlinks + + +common_lib_symlinks = create_symlink_list("env", False) +for item in common_lib_symlinks: + print(" ", item) +# for env in envs: +# env_symlinks = create_symlink_list(env, False) + +# %% diff --git a/pioScripts/target_pio_versions.py b/pioScripts/target_pio_versions.py new file mode 100644 index 000000000..ce54dff13 --- /dev/null +++ b/pioScripts/target_pio_versions.py @@ -0,0 +1,15 @@ +Import("env") + +# https://docs.platformio.org/en/latest/scripting/custom_targets.html + +# Single action/command per 1 target +env.AddCustomTarget("sysenv", None, 'python -c "import os; print(os.environ)"') + +# Multiple actions +env.AddCustomTarget( + name="pioenv", + dependencies=None, + actions=["pio --version", "python --version"], + title="Core Env", + description="Show PlatformIO Core and Python versions", +) From 7bedc43118a6c8410177ad5a4b15bd09d5638130 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 7 Aug 2024 09:06:42 -0400 Subject: [PATCH 094/138] Update pio scripts Signed-off-by: Sara Damiano --- .gitignore | 3 - examples/example_dependencies.json | 31 ++ pioScripts/install_shared_deps.py | 218 ------------ pioScripts/install_working_dependencies.py | 364 +++++++++++---------- 4 files changed, 231 insertions(+), 385 deletions(-) create mode 100644 examples/example_dependencies.json delete mode 100644 pioScripts/install_shared_deps.py diff --git a/.gitignore b/.gitignore index de92a0101..de1e869e4 100644 --- a/.gitignore +++ b/.gitignore @@ -104,9 +104,6 @@ arduino_cli.log **/sensor_tests/* docs/Doxyfile.bak continuous_integration/platformio_ci_local.ini -pioScripts/install_shared_deps.py runDoxygen_archive.bat generateKeywords.bat update_path.bat -pioScripts/install_working_dependencies.py -pioScripts/target_pio_versions.py diff --git a/examples/example_dependencies.json b/examples/example_dependencies.json new file mode 100644 index 000000000..6a23cb5d7 --- /dev/null +++ b/examples/example_dependencies.json @@ -0,0 +1,31 @@ +{ + "action_cache_version": 1, + "dependencies": [ + { + "name": "Adafruit SHT4x Library", + "owner": "adafruit", + "library id": "11710", + "url": "https://github.com/adafruit/Adafruit_SHT4X", + "version": "~1.0.4", + "note": "Sensirion SHT4x Library by Adafruit", + "authors": ["Adafruit"], + "frameworks": "arduino" + }, + { + "name": "SDI-12", + "owner": "envirodiy", + "library id": "1486", + "version": "~2.1.4", + "url": "https://github.com/EnviroDIY/Arduino-SDI-12", + "note": "EnviroDIY SDI-12 Library for Arduino", + "author_notes": [ + "Kevin M. Smith", + "Sara Damiano", + "Shannon Hicks", + "Anthony Aufdenkampe" + ], + "frameworks": "arduino", + "platforms": "atmelavr, atmelsam" + } + ] +} diff --git a/pioScripts/install_shared_deps.py b/pioScripts/install_shared_deps.py deleted file mode 100644 index 00aed2b13..000000000 --- a/pioScripts/install_shared_deps.py +++ /dev/null @@ -1,218 +0,0 @@ -from SCons.Script import ( - ARGUMENTS, - BUILD_TARGETS, - COMMAND_LINE_TARGETS, - AlwaysBuild, - Builder, - Default, - DefaultEnvironment, -) -import subprocess -from os import makedirs -from os.path import isdir -import re - -Import("env") - -if "idedata" in COMMAND_LINE_TARGETS: - env.Exit(0) - -if env.IsCleanTarget(): - print("==== WE WANT TO DO A CLEAN ====") - -if env.IsIntegrationDump(): - print("==== INTEGRATION DUMP ====") - -# print("Working on environment (PIOENV) {}".format(env["PIOENV"])) -# print( -# "Project workspace directory (PROJECT_WORKSPACE_DIR): {}".format( -# env["PROJECT_WORKSPACE_DIR"] -# ) -# ) -# print("Project source directory (PROJECT_SRC_DIR): {}".format(env["PROJECT_SRC_DIR"])) -# print( -# "Project build directory (PROJECT_BUILD_DIR): {}".format(env["PROJECT_BUILD_DIR"]) -# ) -# print("Enviroment build directory: {}".format(env["BUILD_DIR"])) -# print("Project lib deps directory: {}".format(env["PROJECT_LIBDEPS_DIR"])) -# print("Enviroment lib path: {}".format(env["LIBPATH"])) -# print("Enviroment lib source directories: {}".format(env["LIBSOURCE_DIRS"])) - -print("\nInstalling and updating common libraries") - - -def get_shared_lib_dir(env): - # Get shared_lib_dir - return env.GetProjectOption("custom_shared_lib_dir") - - -def get_shared_lib_deps(env): - # Get lib_deps - config = env.GetProjectConfig() - raw_lib_deps = env.GetProjectOption("custom_shared_lib_deps") - lib_deps = config.parse_multi_values(raw_lib_deps) - return lib_deps - - -def get_ignored_lib_deps(env): - # Get lib_deps - config = env.GetProjectConfig() - raw_lib_ignore = env.GetProjectOption("lib_ignore") - lib_ignore = config.parse_multi_values(raw_lib_ignore) - return lib_ignore - - -pio_pkg_command = [env.subst("$PYTHONEXE"), "-m", "platformio", "pkg"] - - -def install_shared_dependencies(env, verbose): - # Add verbose text - if int(verbose) >= 1: - print("Installing to {}".format(get_shared_lib_dir(env))) - - # Create shared_lib_dirif it does not exist - if not isdir(get_shared_lib_dir(env)): - if int(verbose) >= 1: - print( - "Directory {} doesn't exist, creating it".format( - get_shared_lib_dir(env) - ) - ) - makedirs(get_shared_lib_dir(env)) - - # Build dependency installation command - install_cmd = pio_pkg_command + ["install"] - install_cmd.extend(["--storage-dir", get_shared_lib_dir(env)]) - - # # Add verbose to command - # if int(verbose) < 1: - # install_cmd.append("-s") - - # Add dependencies to command - for lib in get_shared_lib_deps(env): - install_cmd.append("-l") - install_cmd.append(lib) - - # Run command - # print(install_cmd) - install_result = subprocess.run( - install_cmd, capture_output=True, text=True, check=True - ) - print(install_result.stdout) - print(install_result.stderr) - - -def update_shared_dependencies(env, verbose): - # Build dependency update command - update_cmd = pio_pkg_command + ["update", "-g"] - - # Add verbose to command - if int(verbose) < 1: - update_cmd.append("-s") - - # set the storage directory for the libraries - update_cmd.extend(["--storage-dir", get_shared_lib_dir(env)]) - - # Add dependencies to command - for lib in get_shared_lib_deps(env): - update_cmd.append("-l") - update_cmd.append(lib) - - # Run update command - print("Updating libraries") - # print(update_cmd) - update_result = subprocess.run( - update_cmd, capture_output=True, text=True, check=True - ) - print(update_result.stdout) - print(update_result.stderr) - - -def parse_global_installs(env, verbose): - # Build dependency list command - # pio pkg list -v -g --only-libraries --storage-dir "C:\Users\sdamiano\Documents\GitHub\EnviroDIY\ModularSensors\.pio\libdeps\shared" - list_cmd = pio_pkg_command + [ - "list", - "-g", - "--only-libraries", - ] - - # Add verbose to command - if int(verbose) >= 1: - list_cmd.append("-v") - - # set the storage directory for the libraries - list_cmd.extend(["--storage-dir", get_shared_lib_dir(env)]) - - # Run update command - print("Listing libraries") - # print(list_cmd) - list_result = subprocess.run(list_cmd, capture_output=True, text=True, check=True) - # print(list_result.stdout) - # print(list_result.stderr) - - lib_list_presort = [] - - for line in list_result.stdout.split("\n"): - if int(verbose) >= 1: - print(line) - # print(line.split()) - match = re.search( - r".*? (?P[\w\s-]*?) @ (?P[\w\s\.\+-]*?) \(required: (?:git\+)?(?P.*?)(?: @ .*?)?, (?P.*?)\)", - line, - ) - if match: - if int(verbose) >= 1: - print("Library name: {}".format(match.group("lib_name"))) - print("Library Version: {}".format(match.group("lib_version"))) - print("Library Req: {}".format(match.group("lib_req"))) - print("Library Storage Dir: {}".format(match.group("lib_dir"))) - shared_entry = list( - filter( - lambda x: match.group("lib_req").lower() in x.lower(), - get_shared_lib_deps(env), - ) - ) - is_in_shared = len(shared_entry) > 0 - if is_in_shared: - shared_position = get_shared_lib_deps(env).index(shared_entry[0]) - else: - shared_position = -1 - is_ignored = match.group("lib_name") in get_ignored_lib_deps(env) - match_groups = match.groupdict() - match_groups["shared_entry"] = shared_entry - match_groups["is_in_shared"] = is_in_shared - match_groups["is_ignored"] = is_ignored - match_groups["shared_position"] = shared_position - lib_list_presort.append(match_groups) - else: - if int(verbose) >= 1: - print("XXXXXXXXXXXXXXXXXXXXXXX NO MATCH XXXXXXXXXXXXXXXXXXXXXXX") - if int(verbose) >= 1: - print("##########") - - lib_list = sorted(lib_list_presort, key=lambda d: d["shared_position"]) - if int(verbose) >= 1: - print(lib_list) - - lib_used = [] - for lib in lib_list: - if not lib["is_ignored"]: - lib_used.append(f"{lib['lib_name']}=symlink://{lib['lib_dir']}") - if int(verbose) >= 1: - print(lib_used) - - platform = env.PioPlatform() - prev_lib_deps = env.GetProjectOption("lib_deps") - new_lib_deps = prev_lib_deps + lib_used - env_section = "env:" + env["PIOENV"] - platform.config.set(env_section, "lib_deps", new_lib_deps) - - -# Get verbose level -VERBOSE = ARGUMENTS.get("PIOVERBOSE", 0) - -# Intall dependencies listed in env shared_lib_deps to shared_lib_dir -install_shared_dependencies(env, VERBOSE) -update_shared_dependencies(env, VERBOSE) -parse_global_installs(env, VERBOSE) diff --git a/pioScripts/install_working_dependencies.py b/pioScripts/install_working_dependencies.py index 8c75bb4da..02c264e9a 100644 --- a/pioScripts/install_working_dependencies.py +++ b/pioScripts/install_working_dependencies.py @@ -3,15 +3,6 @@ import os import sys from typing import Union -from SCons.Script import ( - ARGUMENTS, - BUILD_TARGETS, - COMMAND_LINE_TARGETS, - AlwaysBuild, - Builder, - Default, - DefaultEnvironment, -) import subprocess from os import makedirs from os.path import isdir @@ -19,43 +10,55 @@ import json from platformio.project.config import ProjectConfig - -# from platformio.package.meta import PackageSpec +from platformio.package.meta import PackageSpec # %% -Import("env") -print("Working on environment (PIOENV) {}".format(env["PIOENV"])) -print("Enviroment and project settings:") -for project_directory in [ - "PROJECT_DIR", - "PROJECT_CORE_DIR", - "PROJECT_PACKAGES_DIR", - "PROJECT_WORKSPACE_DIR", - "PROJECT_INCLUDE_DIR", - "PROJECT_SRC_DIR", - "PROJECT_TEST_DIR", - "PROJECT_DATA_DIR", - "PROJECT_BUILD_DIR", - "PROJECT_LIBDEPS_DIR", - "LIBSOURCE_DIRS", - "LIBPATH", - "PIOENV", - "BUILD_DIR", - "BUILD_TYPE", - "BUILD_CACHE_DIR", - "LINKFLAGS", -]: - print(f"{project_directory}: {env[project_directory]}") - - -shared_lib_dir = env["LIBSOURCE_DIRS"][0] -shared_lib_abbr = ".pio/libdeps/shared" -project_ini_file = f"{env['PROJECT_DIR']}\\platformio.ini" -library_json_file = f"{env['PROJECT_DIR']}\\library.json" -examples_deps_file = f"{env['PROJECT_DIR']}\\examples\\example_dependencies.json" - -proj_config = ProjectConfig(path=project_ini_file) +try: + # Import the current working construction + # environment to the `env` variable. + # alias of `env = DefaultEnvironment()` + Import("env") + + print("Working on environment (PIOENV) {}".format(env["PIOENV"])) + print("Enviroment and project settings:") + for project_directory in [ + "PROJECT_DIR", + "PROJECT_CORE_DIR", + "PROJECT_PACKAGES_DIR", + "PROJECT_WORKSPACE_DIR", + "PROJECT_INCLUDE_DIR", + "PROJECT_SRC_DIR", + "PROJECT_TEST_DIR", + "PROJECT_DATA_DIR", + "PROJECT_BUILD_DIR", + "PROJECT_LIBDEPS_DIR", + "LIBSOURCE_DIRS", + "LIBPATH", + "PIOENV", + "BUILD_DIR", + "BUILD_TYPE", + "BUILD_CACHE_DIR", + "LINKFLAGS", + ]: + print(f"{project_directory}: {env[project_directory]}") + + shared_lib_dir = env["LIBSOURCE_DIRS"][0] + shared_lib_abbr = "lib" + project_ini_file = f"{env['PROJECT_DIR']}\\platformio.ini" + library_json_file = f"{env['PROJECT_DIR']}\\library.json" + examples_deps_file = f"{env['PROJECT_DIR']}\\examples\\example_dependencies.json" + proj_config = env.GetProjectConfig() + env_name = env["PIOENV"] +except: + shared_lib_dir = f"{os.getcwd()}\\..\\lib" + shared_lib_abbr = "lib" + project_ini_file = f"{os.getcwd()}\\..\\platformio.ini" + library_json_file = f"{os.getcwd()}\\..\\library.json" + examples_deps_file = f"{os.getcwd()}\\..\\examples\\example_dependencies.json" + proj_config = ProjectConfig.get_instance(path=project_ini_file) + env_name = proj_config.get_default_env() + envs = proj_config.envs() @@ -63,59 +66,169 @@ # find dependencies in the platformio.ini file def get_shared_lib_deps(env): # Get lib_deps - config = env.GetProjectConfig() - raw_lib_deps = env.GetProjectOption("custom_shared_lib_deps", "") - lib_deps = config.parse_multi_values(raw_lib_deps) - return lib_deps - # convert to dict, taking advantage of PlatformIO's PackageSpec parser - # lib_deps = [] - # for raw_lib_dep in raw_lib_deps: - # spec = PackageSpec(raw_lib_dep) - # dep_dict = {} - # if spec.owner is not None: - # dep_dict["owner"] = spec.owner - # if spec.name is not None: - # dep_dict["name"] = spec.name - # if spec.uri is not None: - # dep_dict["version"] = spec.uri - # elif spec.requirements is not None: - # dep_dict["version"] = spec.requirements - # lib_deps.append(copy.deepcopy(dep_dict)) + raw_lib_deps = proj_config.get( + section=f"env:{env}", option="custom_shared_lib_deps", default="" + ) + lib_deps = proj_config.parse_multi_values(raw_lib_deps) # return lib_deps + # convert to a PlatformIO PackageSpec + lib_deps_specs = [] + for lib_deps in lib_deps: + spec = PackageSpec(lib_deps) + lib_deps_specs.append(copy.deepcopy(spec)) + return lib_deps_specs def get_ignored_lib_deps(env): - return proj_config.get(section=f"env:{env}", option="lib_ignore") + return proj_config.get(section=f"env:{env}", option="lib_ignore", default=[]) # find dependencies based on the library specification -if os.path.isfile(os.path.join(env["PROJECT_DIR"], "library.json")): - with open(os.path.join(env["PROJECT_DIR"], "library.json")) as f: +if os.path.isfile(library_json_file): + with open(library_json_file) as f: library_specs = json.load(f) else: library_specs = {"dependencies": []} # find dependencies based on the examples -if os.path.isfile( - os.path.join(env["PROJECT_DIR"], "examples/example_dependencies.json") -): - with open( - os.path.join(env["PROJECT_DIR"], "examples/example_dependencies.json") - ) as f: +if os.path.isfile(examples_deps_file): + with open(examples_deps_file) as f: example_specs = json.load(f) else: example_specs = {"dependencies": []} -dependencies = get_shared_lib_deps(env) + +def get_package_spec(dependency: dict): + spec = PackageSpec( + id=dependency.get("id"), + owner=dependency.get("owner"), + name=dependency.get("name"), + requirements=dependency.get("version"), + ) + return spec + + +def convert_dep_dict_to_str(dependency: dict, include_version: bool = True) -> str: + install_str = "" + if "owner" in dependency.keys() and "github" in dependency["version"]: + if "name" in dependency.keys(): + install_str += f"{dependency['name']}=" + install_str += dependency["version"] + elif ( + "owner" in dependency.keys() + and "name" in dependency.keys() + and "version" in dependency.keys() + ): + lib_dep = f"{dependency['owner']}/{dependency['name']}" + if include_version: + lib_dep += f"@{dependency['version']}" + install_str += lib_dep + elif "name" in dependency.keys() and "version" in dependency.keys(): + lib_dep = f"{dependency['name']}" + if include_version: + lib_dep += f"@{dependency['version']}" + install_str += lib_dep + else: + install_str += dependency["name"] + + return install_str + + +dependencies = get_shared_lib_deps(env_name) if "dependencies" in library_specs.keys(): - dependencies.extend(library_specs["dependencies"]) + dependencies.extend( + [get_package_spec(dependency) for dependency in library_specs["dependencies"]] + ) if "dependencies" in example_specs.keys(): - dependencies.extend(example_specs["dependencies"]) + dependencies.extend( + [get_package_spec(dependency) for dependency in example_specs["dependencies"]] + ) + +humanized_deps = [dep.as_dependency() for dep in dependencies] # quit if there are no dependencies if len(dependencies) == 0: print("No dependencies to install!") sys.exit() + +# %% +# check what's already installed +def parse_global_installs(verbose: bool = False): + # Build dependency list command + list_cmd = ["pio", "pkg", "list", "-g", "--only-libraries", "-v"] + + # set the storage directory for the libraries + list_cmd.extend(["--storage-dir", shared_lib_dir]) + + # Run list command + # print("Listing libraries") + # print(list_cmd) + list_result = subprocess.run(list_cmd, capture_output=True, text=True, check=True) + # print(list_result.stdout) + # print(list_result.stderr) + + lib_list_presort = [] + + for line in list_result.stdout.split("\n"): + if int(verbose) >= 1: + print(line) + # print(line.split()) + match = re.search( + r".*? (?P[\w\s-]*?) @ (?P[\w\s\.\+-]*?) \(required: (?:git\+)?(?P.*?)(?: @ .*?)?, (?P.*?)\)", + line, + ) + if match: + if int(verbose) >= 1: + print("Library name: {}".format(match.group("lib_name"))) + print("Library Version: {}".format(match.group("lib_version"))) + print("Library Req: {}".format(match.group("lib_req"))) + print("Library Storage Dir: {}".format(match.group("lib_dir"))) + req_entry = list( + filter( + lambda x: match.group("lib_req").lower() in x.lower(), + humanized_deps, + ) + ) + is_in_reqs = len(req_entry) > 0 + if is_in_reqs: + req_position = humanized_deps.index(req_entry[0]) + else: + req_position = -1 + if match.group("lib_name") == "Adafruit BusIO": + req_position = -2 + match_groups = match.groupdict() + match_groups["req_entry"] = req_entry + match_groups["is_in_reqs"] = is_in_reqs + match_groups["req_position"] = req_position + lib_list_presort.append(match_groups) + else: + if int(verbose) >= 1: + print("XXXXXXXXXXXXXXXXXXXXXXX NO MATCH XXXXXXXXXXXXXXXXXXXXXXX") + if int(verbose) >= 1: + print("##########") + + lib_list = sorted(lib_list_presort, key=lambda d: d["req_position"]) + if int(verbose) >= 1: + print(lib_list) + return lib_list + + +lib_list = parse_global_installs(False) +print(lib_list) + +# decide what to install and what to update +libs_to_install = [] +libs_to_update = [] +for dep_spec in dependencies: + print() + if f"{dep_spec.owner}/{dep_spec.name}".lower() not in [ + lib["lib_req"].lower() for lib in lib_list + ]: + libs_to_install.append(dep_spec) + else: + libs_to_update.append(dep_spec) + + # %% print(f"\nInstalling and updating common libraries in {shared_lib_dir}") @@ -125,7 +238,7 @@ def get_ignored_lib_deps(env): def create_pio_ci_command( - library: Union[dict | str], + library: Union[str | dict | PackageSpec], update: bool = True, include_version: bool = True, ) -> list: @@ -139,47 +252,29 @@ def create_pio_ci_command( shared_lib_dir, "--library", ] - if isinstance(library, str): + if isinstance(library, PackageSpec): + pio_command_args.append(library.as_dependency()) + return pio_command_args + elif isinstance(library, dict): + pio_command_args.append(convert_dep_dict_to_str(library)) + return pio_command_args + elif isinstance(library, str): pio_command_args.append(library) return pio_command_args - if "owner" in library.keys() and "github" in library["version"]: - pio_command_args.append(library["version"]) - elif ( - "owner" in library.keys() - and "name" in library.keys() - and "version" in library.keys() - ): - lib_dep = f"{library['owner']}/{library['name']}" - if include_version: - lib_dep += f"@{library['version']}" - pio_command_args.append(lib_dep) - elif "name" in library.keys() and "version" in library.keys(): - lib_dep = f"{library['name']}" - if include_version: - lib_dep += f"@{library['version']}" - pio_command_args.append(lib_dep) - else: - pio_command_args.append(library["name"]) - return pio_command_args - - -deps_to_install = [] - # %% def install_shared_dependencies(verbose): if verbose: print("\nInstalling libraries") - for lib in dependencies: + for lib in libs_to_install: lib_install_cmd = create_pio_ci_command( library=lib, update=False, include_version=True ) - deps_to_install.extend(lib_install_cmd[-1]) # Run command - print(lib_install_cmd) + # print(lib_install_cmd) if verbose: print(f"Installing {lib}") install_result = subprocess.run( @@ -197,13 +292,13 @@ def update_shared_dependencies(verbose): if verbose: print("\nUpdating libraries") - for lib in dependencies: + for lib in libs_to_update: lib_update_cmd = create_pio_ci_command( library=lib, update=True, include_version=False ) # Run update command - print(lib_update_cmd) + # print(lib_update_cmd) if verbose: print(f"Updating {lib}") update_result = subprocess.run( @@ -217,68 +312,9 @@ def update_shared_dependencies(verbose): # %% -def parse_global_installs(verbose: bool = False): - # Build dependency list command - # pio pkg list -v -g --only-libraries --storage-dir "C:\Users\sdamiano\Documents\GitHub\EnviroDIY\ModularSensors\.pio\libdeps\shared" - list_cmd = ["pio", "pkg", "list", "-g", "--only-libraries", "-v"] - - # set the storage directory for the libraries - list_cmd.extend(["--storage-dir", shared_lib_dir]) - - # Run update command - # print("Listing libraries") - # print(list_cmd) - list_result = subprocess.run(list_cmd, capture_output=True, text=True, check=True) - # print(list_result.stdout) - # print(list_result.stderr) - - lib_list_presort = [] - - for line in list_result.stdout.split("\n"): - if int(verbose) >= 1: - print(line) - # print(line.split()) - match = re.search( - r".*? (?P[\w\s-]*?) @ (?P[\w\s\.\+-]*?) \(required: (?:git\+)?(?P.*?)(?: @ .*?)?, (?P.*?)\)", - line, - ) - if match: - if int(verbose) >= 1: - print("Library name: {}".format(match.group("lib_name"))) - print("Library Version: {}".format(match.group("lib_version"))) - print("Library Req: {}".format(match.group("lib_req"))) - print("Library Storage Dir: {}".format(match.group("lib_dir"))) - shared_entry = list( - filter( - lambda x: match.group("lib_req").lower() in x.lower(), - deps_to_install, - ) - ) - is_in_shared = len(shared_entry) > 0 - if is_in_shared: - shared_position = deps_to_install.index(shared_entry[0]) - else: - shared_position = -1 - if match.group("lib_name") == "Adafruit BusIO": - shared_position = -2 - match_groups = match.groupdict() - match_groups["shared_entry"] = shared_entry - match_groups["is_in_shared"] = is_in_shared - match_groups["shared_position"] = shared_position - lib_list_presort.append(match_groups) - else: - if int(verbose) >= 1: - print("XXXXXXXXXXXXXXXXXXXXXXX NO MATCH XXXXXXXXXXXXXXXXXXXXXXX") - if int(verbose) >= 1: - print("##########") - - lib_list = sorted(lib_list_presort, key=lambda d: d["shared_position"]) - if int(verbose) >= 1: - print(lib_list) - return lib_list - - +# check what's now installed lib_list = parse_global_installs(False) +print(lib_list) # %% From b73f08eacd3f72f5b7540613e9a836050c53276a Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 7 Aug 2024 09:17:46 -0400 Subject: [PATCH 095/138] Update pio scripts again Signed-off-by: Sara Damiano --- .gitignore | 18 ++++++++---------- pioScripts/install_working_dependencies.py | 15 ++++++++++----- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index de1e869e4..3b43519d4 100644 --- a/.gitignore +++ b/.gitignore @@ -47,22 +47,22 @@ Network Trash Folder Temporary Items .apdisk +# Python +__pycache__/ + # PyCharm .idea/ -# Atom / PlatformIO -.pio -.pioenvs -.piolibdeps -.pio -.pio/libdeps -.pio/build +# Atom +.atomrc.cson + +# PlatformIO .pio/* .clang_complete .gcc-flags.json -.atomrc.cson lib/* include/* +boards/* /platformio.ini .sconsign.dblite @@ -80,8 +80,6 @@ YosemitechDO/ LongTermLogger/ barometric_correction/ 3G_Test/ - -__pycache__/ runDoxygen.bat docs/examples/* docs/examples.dox_x diff --git a/pioScripts/install_working_dependencies.py b/pioScripts/install_working_dependencies.py index 02c264e9a..eee3beafa 100644 --- a/pioScripts/install_working_dependencies.py +++ b/pioScripts/install_working_dependencies.py @@ -161,11 +161,16 @@ def parse_global_installs(verbose: bool = False): list_cmd.extend(["--storage-dir", shared_lib_dir]) # Run list command - # print("Listing libraries") - # print(list_cmd) - list_result = subprocess.run(list_cmd, capture_output=True, text=True, check=True) - # print(list_result.stdout) - # print(list_result.stderr) + print("Listing libraries") + print(" ".join(list_cmd)) + try: + list_result = subprocess.run( + list_cmd, capture_output=True, text=True, check=True + ) + # print(list_result.stdout) + # print(list_result.stderr) + except: + return [] lib_list_presort = [] From 4ac4b6f901813f8d6884f73507fd9e2fdc7ba7b8 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 7 Aug 2024 13:25:45 -0400 Subject: [PATCH 096/138] Correct example dependencies Signed-off-by: Sara Damiano --- examples/example_dependencies.json | 39 +++++++++++++----------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/examples/example_dependencies.json b/examples/example_dependencies.json index 6a23cb5d7..787d94b4d 100644 --- a/examples/example_dependencies.json +++ b/examples/example_dependencies.json @@ -2,30 +2,25 @@ "action_cache_version": 1, "dependencies": [ { - "name": "Adafruit SHT4x Library", - "owner": "adafruit", - "library id": "11710", - "url": "https://github.com/adafruit/Adafruit_SHT4X", - "version": "~1.0.4", - "note": "Sensirion SHT4x Library by Adafruit", - "authors": ["Adafruit"], - "frameworks": "arduino" + "name": "StreamDebugger", + "owner": "vshymanskyy", + "version": "~1.0.1" }, { - "name": "SDI-12", - "owner": "envirodiy", - "library id": "1486", - "version": "~2.1.4", - "url": "https://github.com/EnviroDIY/Arduino-SDI-12", - "note": "EnviroDIY SDI-12 Library for Arduino", - "author_notes": [ - "Kevin M. Smith", - "Sara Damiano", - "Shannon Hicks", - "Anthony Aufdenkampe" - ], - "frameworks": "arduino", - "platforms": "atmelavr, atmelsam" + "name": "NeoSWSerial", + "version": "https://github.com/SRGDamia1/NeoSWSerial.git" + }, + { + "name": "AltSoftSerial", + "version": "https://github.com/PaulStoffregen/AltSoftSerial.git" + }, + { + "name": "SoftwareWire", + "version": "https://github.com/Testato/SoftwareWire.git#v1.5.1" + }, + { + "name": "SoftwareSerial_ExternalInts", + "version": "https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git" } ] } From d7d06097ecfcb2d9488e889a0789a29270f4c498 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 7 Aug 2024 13:29:15 -0400 Subject: [PATCH 097/138] Update pio scripts for better ignore Signed-off-by: Sara Damiano --- .gitignore | 1 + pioScripts/install_working_dependencies.py | 123 +++++++++++++++------ 2 files changed, 88 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index 3b43519d4..ec6909142 100644 --- a/.gitignore +++ b/.gitignore @@ -105,3 +105,4 @@ continuous_integration/platformio_ci_local.ini runDoxygen_archive.bat generateKeywords.bat update_path.bat +pio_common_libdeps.ini diff --git a/pioScripts/install_working_dependencies.py b/pioScripts/install_working_dependencies.py index eee3beafa..f0c4cb9b3 100644 --- a/pioScripts/install_working_dependencies.py +++ b/pioScripts/install_working_dependencies.py @@ -46,6 +46,7 @@ shared_lib_dir = env["LIBSOURCE_DIRS"][0] shared_lib_abbr = "lib" project_ini_file = f"{env['PROJECT_DIR']}\\platformio.ini" + libdeps_ini_file = f"{env['PROJECT_DIR']}\\pio_common_libdeps.ini" library_json_file = f"{env['PROJECT_DIR']}\\library.json" examples_deps_file = f"{env['PROJECT_DIR']}\\examples\\example_dependencies.json" proj_config = env.GetProjectConfig() @@ -54,6 +55,7 @@ shared_lib_dir = f"{os.getcwd()}\\..\\lib" shared_lib_abbr = "lib" project_ini_file = f"{os.getcwd()}\\..\\platformio.ini" + libdeps_ini_file = f"{os.getcwd()}\\pio_common_libdeps.ini" library_json_file = f"{os.getcwd()}\\..\\library.json" examples_deps_file = f"{os.getcwd()}\\..\\examples\\example_dependencies.json" proj_config = ProjectConfig.get_instance(path=project_ini_file) @@ -65,13 +67,13 @@ # %% # find dependencies in the platformio.ini file def get_shared_lib_deps(env): - # Get lib_deps + # Get lib_deps in the custom shared_lib_deps folder raw_lib_deps = proj_config.get( section=f"env:{env}", option="custom_shared_lib_deps", default="" ) lib_deps = proj_config.parse_multi_values(raw_lib_deps) - # return lib_deps - # convert to a PlatformIO PackageSpec + + # convert each custom lib_dep to a PlatformIO PackageSpec lib_deps_specs = [] for lib_deps in lib_deps: spec = PackageSpec(lib_deps) @@ -89,7 +91,7 @@ def get_ignored_lib_deps(env): library_specs = json.load(f) else: library_specs = {"dependencies": []} -# find dependencies based on the examples +# find dependencies based on the examples dependency specs if os.path.isfile(examples_deps_file): with open(examples_deps_file) as f: example_specs = json.load(f) @@ -162,7 +164,8 @@ def parse_global_installs(verbose: bool = False): # Run list command print("Listing libraries") - print(" ".join(list_cmd)) + if int(verbose) >= 1: + print(" ".join(list_cmd)) try: list_result = subprocess.run( list_cmd, capture_output=True, text=True, check=True @@ -251,7 +254,7 @@ def create_pio_ci_command( "pio", "pkg", "update" if update else "install", - "--skip-dependencies", + # "--skip-dependencies", "-g", "--storage-dir", shared_lib_dir, @@ -270,7 +273,7 @@ def create_pio_ci_command( # %% def install_shared_dependencies(verbose): - if verbose: + if int(verbose) >= 1: print("\nInstalling libraries") for lib in libs_to_install: @@ -278,10 +281,10 @@ def install_shared_dependencies(verbose): library=lib, update=False, include_version=True ) - # Run command - # print(lib_install_cmd) - if verbose: + if int(verbose) >= 1: print(f"Installing {lib}") + print(" ".join(lib_install_cmd)) + # Run command install_result = subprocess.run( lib_install_cmd, capture_output=True, text=True, check=True ) @@ -294,7 +297,7 @@ def install_shared_dependencies(verbose): # %% def update_shared_dependencies(verbose): - if verbose: + if int(verbose) >= 1: print("\nUpdating libraries") for lib in libs_to_update: @@ -302,10 +305,10 @@ def update_shared_dependencies(verbose): library=lib, update=True, include_version=False ) - # Run update command - # print(lib_update_cmd) - if verbose: + if int(verbose) >= 1: print(f"Updating {lib}") + print(" ".join(lib_update_cmd)) + # Run update command update_result = subprocess.run( lib_update_cmd, capture_output=True, text=True, check=True ) @@ -324,40 +327,88 @@ def update_shared_dependencies(verbose): # %% def create_symlink_list(environment: str, verbose: bool = False): - lib_symlinks = [] + all_symlinks = [] + req_symlinks = [] ign_symlinks = [] + other_symlinks = [] print("Creating symlink list") for lib in lib_list: - is_ignored = lib["lib_name"] in get_ignored_lib_deps(environment) - if not is_ignored or lib["lib_name"] in [ - "Adafruit GFX Library", - "Adafruit SSD1306", - ]: - lib_symlinks.append( - f"{lib['lib_name']}=symlink://{lib['lib_dir']}".replace( - shared_lib_dir, shared_lib_abbr - ) - .replace("\\\\", "/") - .replace("\\", "/") + symlink = ( + f"{lib['lib_name']}=symlink://{lib['lib_dir']}".replace( + shared_lib_dir, shared_lib_abbr ) + .replace("\\\\", "/") + .replace("\\", "/") + ) + all_symlinks.append(symlink) + is_req = lib["is_in_reqs"] + is_ignored = lib["lib_name"] in get_ignored_lib_deps(environment) + if is_req: + req_symlinks.append(symlink) + elif is_ignored: + ign_symlinks.append(symlink) else: - ign_symlinks.append( - f"{lib['lib_name']}=symlink://{lib['lib_dir']}".replace( - shared_lib_dir, shared_lib_abbr - ) - .replace("\\\\", "/") - .replace("\\", "/") - ) + other_symlinks.append(symlink) if int(verbose) >= 1: - print(lib_symlinks) + print(other_symlinks) - return lib_symlinks + return { + "all_symlinks": all_symlinks, + "req_symlinks": req_symlinks, + "ign_symlinks": ign_symlinks, + "other_symlinks": other_symlinks, + } common_lib_symlinks = create_symlink_list("env", False) -for item in common_lib_symlinks: +print("<<<<<<<<<<<>>>>>>>>>>>") +for item in common_lib_symlinks["req_symlinks"]: + print(" ", item) +print("<<<<<<<<<<<>>>>>>>>>>>") +for item in common_lib_symlinks["ign_symlinks"]: + print(" ", item) +print("<<<<<<<<<<<>>>>>>>>>>>") +for item in common_lib_symlinks["other_symlinks"]: print(" ", item) # for env in envs: # env_symlinks = create_symlink_list(env, False) + +# %% +with open(libdeps_ini_file, "w+") as out_file: + out_file.write( + "; File Automatically Generated by pioScripts/install_working_dependencies.py\n" + ) + out_file.write("; DO NOT MODIFY\n\n") + out_file.write("; Global data for all [env:***]\n") + out_file.write("[env]\n") + + out_file.write("lib_deps =\n") + for item in common_lib_symlinks["all_symlinks"]: + out_file.write(" ") + out_file.write(item) + out_file.write("\n") + + out_file.write("lib_ignore =\n") + ignored_folders = [ + ".git", + ".pio", + ".vscode", + ".history", + "doc", + "examples", + "extras", + "sensor_tests", + ] + for folder in ignored_folders: + out_file.write(" ") + out_file.write(folder) + out_file.write("\n") + for lib in lib_list: + is_req = lib["is_in_reqs"] + if not is_req: + out_file.write(" ") + out_file.write(lib["lib_name"]) + out_file.write("\n") + # %% From 3e8f5f1a6b889216393049249b384b328a7bcd0c Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 7 Aug 2024 13:31:36 -0400 Subject: [PATCH 098/138] Move pio scripts to the workflows repo Signed-off-by: Sara Damiano --- pioScripts/generate_compile_commands.py | 15 - pioScripts/install_working_dependencies.py | 414 --------------------- pioScripts/pio_set_global_flags.py | 24 -- pioScripts/target_pio_versions.py | 15 - 4 files changed, 468 deletions(-) delete mode 100644 pioScripts/generate_compile_commands.py delete mode 100644 pioScripts/install_working_dependencies.py delete mode 100644 pioScripts/pio_set_global_flags.py delete mode 100644 pioScripts/target_pio_versions.py diff --git a/pioScripts/generate_compile_commands.py b/pioScripts/generate_compile_commands.py deleted file mode 100644 index 8629e5a1a..000000000 --- a/pioScripts/generate_compile_commands.py +++ /dev/null @@ -1,15 +0,0 @@ -import os -import sys - -Import("env") - -if "compiledb" in COMMAND_LINE_TARGETS: - print("Generating compile commands!") - - # include toolchain paths - env.Replace(COMPILATIONDB_INCLUDE_TOOLCHAIN=True) - - # override compilation DB path - env.Replace( - COMPILATIONDB_PATH=os.path.join("$PROJECT_DIR/.vscode", "compile_commands.json") - ) diff --git a/pioScripts/install_working_dependencies.py b/pioScripts/install_working_dependencies.py deleted file mode 100644 index f0c4cb9b3..000000000 --- a/pioScripts/install_working_dependencies.py +++ /dev/null @@ -1,414 +0,0 @@ -# %% -import copy -import os -import sys -from typing import Union -import subprocess -from os import makedirs -from os.path import isdir -import re -import json - -from platformio.project.config import ProjectConfig -from platformio.package.meta import PackageSpec - - -# %% -try: - # Import the current working construction - # environment to the `env` variable. - # alias of `env = DefaultEnvironment()` - Import("env") - - print("Working on environment (PIOENV) {}".format(env["PIOENV"])) - print("Enviroment and project settings:") - for project_directory in [ - "PROJECT_DIR", - "PROJECT_CORE_DIR", - "PROJECT_PACKAGES_DIR", - "PROJECT_WORKSPACE_DIR", - "PROJECT_INCLUDE_DIR", - "PROJECT_SRC_DIR", - "PROJECT_TEST_DIR", - "PROJECT_DATA_DIR", - "PROJECT_BUILD_DIR", - "PROJECT_LIBDEPS_DIR", - "LIBSOURCE_DIRS", - "LIBPATH", - "PIOENV", - "BUILD_DIR", - "BUILD_TYPE", - "BUILD_CACHE_DIR", - "LINKFLAGS", - ]: - print(f"{project_directory}: {env[project_directory]}") - - shared_lib_dir = env["LIBSOURCE_DIRS"][0] - shared_lib_abbr = "lib" - project_ini_file = f"{env['PROJECT_DIR']}\\platformio.ini" - libdeps_ini_file = f"{env['PROJECT_DIR']}\\pio_common_libdeps.ini" - library_json_file = f"{env['PROJECT_DIR']}\\library.json" - examples_deps_file = f"{env['PROJECT_DIR']}\\examples\\example_dependencies.json" - proj_config = env.GetProjectConfig() - env_name = env["PIOENV"] -except: - shared_lib_dir = f"{os.getcwd()}\\..\\lib" - shared_lib_abbr = "lib" - project_ini_file = f"{os.getcwd()}\\..\\platformio.ini" - libdeps_ini_file = f"{os.getcwd()}\\pio_common_libdeps.ini" - library_json_file = f"{os.getcwd()}\\..\\library.json" - examples_deps_file = f"{os.getcwd()}\\..\\examples\\example_dependencies.json" - proj_config = ProjectConfig.get_instance(path=project_ini_file) - env_name = proj_config.get_default_env() - -envs = proj_config.envs() - - -# %% -# find dependencies in the platformio.ini file -def get_shared_lib_deps(env): - # Get lib_deps in the custom shared_lib_deps folder - raw_lib_deps = proj_config.get( - section=f"env:{env}", option="custom_shared_lib_deps", default="" - ) - lib_deps = proj_config.parse_multi_values(raw_lib_deps) - - # convert each custom lib_dep to a PlatformIO PackageSpec - lib_deps_specs = [] - for lib_deps in lib_deps: - spec = PackageSpec(lib_deps) - lib_deps_specs.append(copy.deepcopy(spec)) - return lib_deps_specs - - -def get_ignored_lib_deps(env): - return proj_config.get(section=f"env:{env}", option="lib_ignore", default=[]) - - -# find dependencies based on the library specification -if os.path.isfile(library_json_file): - with open(library_json_file) as f: - library_specs = json.load(f) -else: - library_specs = {"dependencies": []} -# find dependencies based on the examples dependency specs -if os.path.isfile(examples_deps_file): - with open(examples_deps_file) as f: - example_specs = json.load(f) -else: - example_specs = {"dependencies": []} - - -def get_package_spec(dependency: dict): - spec = PackageSpec( - id=dependency.get("id"), - owner=dependency.get("owner"), - name=dependency.get("name"), - requirements=dependency.get("version"), - ) - return spec - - -def convert_dep_dict_to_str(dependency: dict, include_version: bool = True) -> str: - install_str = "" - if "owner" in dependency.keys() and "github" in dependency["version"]: - if "name" in dependency.keys(): - install_str += f"{dependency['name']}=" - install_str += dependency["version"] - elif ( - "owner" in dependency.keys() - and "name" in dependency.keys() - and "version" in dependency.keys() - ): - lib_dep = f"{dependency['owner']}/{dependency['name']}" - if include_version: - lib_dep += f"@{dependency['version']}" - install_str += lib_dep - elif "name" in dependency.keys() and "version" in dependency.keys(): - lib_dep = f"{dependency['name']}" - if include_version: - lib_dep += f"@{dependency['version']}" - install_str += lib_dep - else: - install_str += dependency["name"] - - return install_str - - -dependencies = get_shared_lib_deps(env_name) -if "dependencies" in library_specs.keys(): - dependencies.extend( - [get_package_spec(dependency) for dependency in library_specs["dependencies"]] - ) -if "dependencies" in example_specs.keys(): - dependencies.extend( - [get_package_spec(dependency) for dependency in example_specs["dependencies"]] - ) - -humanized_deps = [dep.as_dependency() for dep in dependencies] - -# quit if there are no dependencies -if len(dependencies) == 0: - print("No dependencies to install!") - sys.exit() - - -# %% -# check what's already installed -def parse_global_installs(verbose: bool = False): - # Build dependency list command - list_cmd = ["pio", "pkg", "list", "-g", "--only-libraries", "-v"] - - # set the storage directory for the libraries - list_cmd.extend(["--storage-dir", shared_lib_dir]) - - # Run list command - print("Listing libraries") - if int(verbose) >= 1: - print(" ".join(list_cmd)) - try: - list_result = subprocess.run( - list_cmd, capture_output=True, text=True, check=True - ) - # print(list_result.stdout) - # print(list_result.stderr) - except: - return [] - - lib_list_presort = [] - - for line in list_result.stdout.split("\n"): - if int(verbose) >= 1: - print(line) - # print(line.split()) - match = re.search( - r".*? (?P[\w\s-]*?) @ (?P[\w\s\.\+-]*?) \(required: (?:git\+)?(?P.*?)(?: @ .*?)?, (?P.*?)\)", - line, - ) - if match: - if int(verbose) >= 1: - print("Library name: {}".format(match.group("lib_name"))) - print("Library Version: {}".format(match.group("lib_version"))) - print("Library Req: {}".format(match.group("lib_req"))) - print("Library Storage Dir: {}".format(match.group("lib_dir"))) - req_entry = list( - filter( - lambda x: match.group("lib_req").lower() in x.lower(), - humanized_deps, - ) - ) - is_in_reqs = len(req_entry) > 0 - if is_in_reqs: - req_position = humanized_deps.index(req_entry[0]) - else: - req_position = -1 - if match.group("lib_name") == "Adafruit BusIO": - req_position = -2 - match_groups = match.groupdict() - match_groups["req_entry"] = req_entry - match_groups["is_in_reqs"] = is_in_reqs - match_groups["req_position"] = req_position - lib_list_presort.append(match_groups) - else: - if int(verbose) >= 1: - print("XXXXXXXXXXXXXXXXXXXXXXX NO MATCH XXXXXXXXXXXXXXXXXXXXXXX") - if int(verbose) >= 1: - print("##########") - - lib_list = sorted(lib_list_presort, key=lambda d: d["req_position"]) - if int(verbose) >= 1: - print(lib_list) - return lib_list - - -lib_list = parse_global_installs(False) -print(lib_list) - -# decide what to install and what to update -libs_to_install = [] -libs_to_update = [] -for dep_spec in dependencies: - print() - if f"{dep_spec.owner}/{dep_spec.name}".lower() not in [ - lib["lib_req"].lower() for lib in lib_list - ]: - libs_to_install.append(dep_spec) - else: - libs_to_update.append(dep_spec) - - -# %% -print(f"\nInstalling and updating common libraries in {shared_lib_dir}") - -# Create shared_lib_dir if it does not exist -if not isdir(shared_lib_dir): - makedirs(shared_lib_dir) - - -def create_pio_ci_command( - library: Union[str | dict | PackageSpec], - update: bool = True, - include_version: bool = True, -) -> list: - pio_command_args = [ - "pio", - "pkg", - "update" if update else "install", - # "--skip-dependencies", - "-g", - "--storage-dir", - shared_lib_dir, - "--library", - ] - if isinstance(library, PackageSpec): - pio_command_args.append(library.as_dependency()) - return pio_command_args - elif isinstance(library, dict): - pio_command_args.append(convert_dep_dict_to_str(library)) - return pio_command_args - elif isinstance(library, str): - pio_command_args.append(library) - return pio_command_args - - -# %% -def install_shared_dependencies(verbose): - if int(verbose) >= 1: - print("\nInstalling libraries") - - for lib in libs_to_install: - lib_install_cmd = create_pio_ci_command( - library=lib, update=False, include_version=True - ) - - if int(verbose) >= 1: - print(f"Installing {lib}") - print(" ".join(lib_install_cmd)) - # Run command - install_result = subprocess.run( - lib_install_cmd, capture_output=True, text=True, check=True - ) - print(install_result.stdout) - # print(install_result.stderr) - - -install_shared_dependencies(True) - - -# %% -def update_shared_dependencies(verbose): - if int(verbose) >= 1: - print("\nUpdating libraries") - - for lib in libs_to_update: - lib_update_cmd = create_pio_ci_command( - library=lib, update=True, include_version=False - ) - - if int(verbose) >= 1: - print(f"Updating {lib}") - print(" ".join(lib_update_cmd)) - # Run update command - update_result = subprocess.run( - lib_update_cmd, capture_output=True, text=True, check=True - ) - print(update_result.stdout) - # print(update_result.stderr) - - -update_shared_dependencies(True) - - -# %% -# check what's now installed -lib_list = parse_global_installs(False) -print(lib_list) - - -# %% -def create_symlink_list(environment: str, verbose: bool = False): - all_symlinks = [] - req_symlinks = [] - ign_symlinks = [] - other_symlinks = [] - print("Creating symlink list") - for lib in lib_list: - symlink = ( - f"{lib['lib_name']}=symlink://{lib['lib_dir']}".replace( - shared_lib_dir, shared_lib_abbr - ) - .replace("\\\\", "/") - .replace("\\", "/") - ) - all_symlinks.append(symlink) - is_req = lib["is_in_reqs"] - is_ignored = lib["lib_name"] in get_ignored_lib_deps(environment) - if is_req: - req_symlinks.append(symlink) - elif is_ignored: - ign_symlinks.append(symlink) - else: - other_symlinks.append(symlink) - if int(verbose) >= 1: - print(other_symlinks) - - return { - "all_symlinks": all_symlinks, - "req_symlinks": req_symlinks, - "ign_symlinks": ign_symlinks, - "other_symlinks": other_symlinks, - } - - -common_lib_symlinks = create_symlink_list("env", False) -print("<<<<<<<<<<<>>>>>>>>>>>") -for item in common_lib_symlinks["req_symlinks"]: - print(" ", item) -print("<<<<<<<<<<<>>>>>>>>>>>") -for item in common_lib_symlinks["ign_symlinks"]: - print(" ", item) -print("<<<<<<<<<<<>>>>>>>>>>>") -for item in common_lib_symlinks["other_symlinks"]: - print(" ", item) -# for env in envs: -# env_symlinks = create_symlink_list(env, False) - - -# %% -with open(libdeps_ini_file, "w+") as out_file: - out_file.write( - "; File Automatically Generated by pioScripts/install_working_dependencies.py\n" - ) - out_file.write("; DO NOT MODIFY\n\n") - out_file.write("; Global data for all [env:***]\n") - out_file.write("[env]\n") - - out_file.write("lib_deps =\n") - for item in common_lib_symlinks["all_symlinks"]: - out_file.write(" ") - out_file.write(item) - out_file.write("\n") - - out_file.write("lib_ignore =\n") - ignored_folders = [ - ".git", - ".pio", - ".vscode", - ".history", - "doc", - "examples", - "extras", - "sensor_tests", - ] - for folder in ignored_folders: - out_file.write(" ") - out_file.write(folder) - out_file.write("\n") - for lib in lib_list: - is_req = lib["is_in_reqs"] - if not is_req: - out_file.write(" ") - out_file.write(lib["lib_name"]) - out_file.write("\n") - -# %% diff --git a/pioScripts/pio_set_global_flags.py b/pioScripts/pio_set_global_flags.py deleted file mode 100644 index 95343342f..000000000 --- a/pioScripts/pio_set_global_flags.py +++ /dev/null @@ -1,24 +0,0 @@ -Import('env') -from os.path import join, realpath - -# append flags to local build environment (for just this library) -env.Append( - CPPDEFINES=[ - ("NEOSWSERIAL_EXTERNAL_PCINT",), - ("SDI12_EXTERNAL_PCINT",) - ] -) -# print ">>>>>LOCAL ENV<<<<<" -# print env.Dump() - -# append the same flags to the global build environment (for all libraries, etc) -global_env = DefaultEnvironment() -global_env.Append( - CPPDEFINES=[ - ("NEOSWSERIAL_EXTERNAL_PCINT",), - ("SDI12_EXTERNAL_PCINT",) - ("MQTT_MAX_PACKET_SIZE",240) - ] -) -# print "<<<<>>>>" -# print global_env.Dump() diff --git a/pioScripts/target_pio_versions.py b/pioScripts/target_pio_versions.py deleted file mode 100644 index ce54dff13..000000000 --- a/pioScripts/target_pio_versions.py +++ /dev/null @@ -1,15 +0,0 @@ -Import("env") - -# https://docs.platformio.org/en/latest/scripting/custom_targets.html - -# Single action/command per 1 target -env.AddCustomTarget("sysenv", None, 'python -c "import os; print(os.environ)"') - -# Multiple actions -env.AddCustomTarget( - name="pioenv", - dependencies=None, - actions=["pio --version", "python --version"], - title="Core Env", - description="Show PlatformIO Core and Python versions", -) From 1ff8b3c89823247d2a5917f94f9ea42df2d4fada Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 8 Aug 2024 16:04:36 -0400 Subject: [PATCH 099/138] Switch to reusable workflows Signed-off-by: Sara Damiano --- .github/dependabot.yml | 2 +- .github/workflows/build_documentation.yaml | 144 +--- .github/workflows/prepare_release.yaml | 184 +---- .../workflows/verify_library_structure.yaml | 95 +-- .gitignore | 32 +- .../generate-documentation.sh | 43 -- continuous_integration/generate_job_matrix.py | 106 ++- .../install-deps-arduino-cli.sh | 159 ----- .../install-deps-platformio.sh | 133 ---- .../install-test-version-arduino-cli.sh | 44 -- docs/Doxyfile | 661 +++++++++++------- examples/example_dependencies.json | 26 + 12 files changed, 577 insertions(+), 1052 deletions(-) delete mode 100644 continuous_integration/generate-documentation.sh delete mode 100644 continuous_integration/install-deps-arduino-cli.sh delete mode 100644 continuous_integration/install-deps-platformio.sh delete mode 100644 continuous_integration/install-test-version-arduino-cli.sh create mode 100644 examples/example_dependencies.json diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0f88bec19..7318fd3ae 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,7 +3,7 @@ updates: - package-ecosystem: 'github-actions' directory: '/' schedule: - interval: 'daily' + interval: 'weekly' labels: - 'CI/CD' commit-message: diff --git a/.github/workflows/build_documentation.yaml b/.github/workflows/build_documentation.yaml index a42b55b39..c834db08f 100644 --- a/.github/workflows/build_documentation.yaml +++ b/.github/workflows/build_documentation.yaml @@ -1,13 +1,19 @@ -name: Check for Complete Documentation +name: Check, Build, and Publish Documentation on: # Triggers the workflow on push or pull request events push: pull_request: # Trigger when a release is created + # NOTE: This will only trigger if the release is created from the UI or with a personal access token release: types: - published + # Trigger with the release workflow finishes + workflow_run: + workflows: ['Create a New Release'] + types: [completed] + branches: [master] # Also give a manual trigger workflow_dispatch: inputs: @@ -21,135 +27,13 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -env: - REBUILD_CACHE_NUMBER: 2 - PYTHON_DEPS_ARCHIVE_NUM: 2 - DOXYGEN_VERSION: Release_1_9_6 - TEX_VERSION: 2019 - # ^^ 2019 is the latest TeX live available on apt-get and that's good enough - GRAPHVIZ_VERSION: 2.43.0 - jobs: - check_menu_inclusion: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" - name: Check that all classes are documented in the menu-a-la-carte example - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - # Using answer from here to get the exit code and pass the output: https://stackoverflow.com/questions/59191913/how-do-i-get-the-output-of-a-specific-step-in-github-actions - - name: check for classes in the menu example - id: check_component - continue-on-error: true - run: | - cd $GITHUB_WORKSPACE/continuous_integration - python check_component_inclusion.py 2>&1 | tee check_component.log - result_code=${PIPESTATUS[0]} - missing_menu_docs=$(cat check_component.log) - missing_menu_docs="${missing_menu_docs//'%'/'%25'}" - missing_menu_docs="${missing_menu_docs//$'\n'/'%0A'}" - missing_menu_docs="${missing_menu_docs//$'\r'/'%0D'}" - echo "missing_menu_docs=missing_menu_docs" >> $GITHUB_OUTPUT - if [[ $result_code ]]; then - echo "$(cat check_component.log)" >> $GITHUB_STEP_SUMMARY - else - echo "Valid library.json =)" >> $GITHUB_STEP_SUMMARY - fi - echo "Finished menu inclusion verification" - exit $result_code - - - name: Create commit comment - uses: peter-evans/commit-comment@v3 - if: steps.check_component.outcome=='failure' - with: - body: | - All sensor and variable subclasses must be included in the Menu a la Carte example - ${{ steps.check_component.outputs.missing_menu_docs }} - - - name: Fail if cannot find all menu flags - id: verification_failure - if: steps.check_component.outcome=='failure' - run: exit 1 - doc_build: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" + if: ${{ (! contains(github.event.head_commit.message, 'ci skip')) && (github.event_name != 'workflow_run' || (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')) }} name: Build documentation - - steps: - # check out the ModularSensors repo - - uses: actions/checkout@v4 - with: - path: code_docs/ModularSensors - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Restore Python Dependencies - uses: actions/cache@v4 - id: cache_python - with: - path: ~/.cache/pip - key: ${{ runner.os }}-python-${{ env.REBUILD_CACHE_NUMBER }}-${{ env.PYTHON_DEPS_ARCHIVE_NUM }} - - - name: Install Pygments and other m.css Python Requirements - run: | - python -m pip install --upgrade pip - pip3 install --upgrade --upgrade-strategy only-if-needed jinja2 Pygments beautifulsoup4 - - - name: Restore Doxygen, Graphviz, and TeX Live - id: cache_doxygen - uses: actions/cache@v4 - with: - path: | - /usr/lib/x86_64-linux-gnu/texlive - /usr/lib/x86_64-linux-gnu/graphviz - doxygen-src - key: ${{ runner.os }}-doxygen-${{ env.REBUILD_CACHE_NUMBER }}-${{ env.DOXYGEN_VERSION }}-${{ env.TEX_VERSION }}-${{ env.GRAPHVIZ_VERSION }} - - - name: Build and install doxygen and its dependencies - if: steps.cache_doxygen.outputs.cache-hit != 'true' - run: | - cd ${{ github.workspace }}/code_docs/ModularSensors/ - chmod +x continuous_integration/build-install-doxygen.sh - sh continuous_integration/build-install-doxygen.sh - - # check out my fork of m.css, for processing Doxygen output - - name: Checkout m.css - uses: actions/checkout@v4 - with: - # Repository name with owner. For example, actions/checkout - repository: SRGDamia1/m.css - path: code_docs/m.css - - - name: Generate all the documentation - continue-on-error: true - run: | - cd ${{ github.workspace }}/code_docs/ModularSensors/ - chmod +x continuous_integration/generate-documentation.sh - sh continuous_integration/generate-documentation.sh 2>&1 | tee doxygen_run_output.log - result_code=${PIPESTATUS[0]} - echo "doxygen_warnings=$(cat docs/output_doxygen.log)" >> $GITHUB_OUTPUT - echo "mcss_warnings=$(cat docs/output_mcss.log)" >> $GITHUB_OUTPUT - echo "## Doxygen completed with the following warnings:" >> $GITHUB_STEP_SUMMARY - echo "$(cat docs/output_doxygen.log)" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "## mcss Doxygen post-processing completed with the following warnings:" >> $GITHUB_STEP_SUMMARY - echo "$(cat docs/output_mcss.log)" >> $GITHUB_STEP_SUMMARY - echo "Finished generating documentation" - exit $result_code - - - name: Deploy to github pages - if: "(github.event_name == 'release' && github.event.action == 'published') || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true')" - uses: peaceiris/actions-gh-pages@v4.0.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ${{ github.workspace }}/code_docs/ModularSensorsDoxygen/m.css + uses: EnviroDIY/workflows/.github/workflows/build_documentation.yaml@main + with: + use_graphviz: false + publish: ${{ (github.event_name == 'release' && github.event.action == 'published') || (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true')}} + rebuild_cache_number: 1 + secrets: inherit diff --git a/.github/workflows/prepare_release.yaml b/.github/workflows/prepare_release.yaml index 07f3fabe8..62f618b3e 100644 --- a/.github/workflows/prepare_release.yaml +++ b/.github/workflows/prepare_release.yaml @@ -7,165 +7,43 @@ on: - 'VERSION' # Push events when the VERSION file changes workflow_dispatch: -name: Prepare a new release and add release assets +name: Create a New Release env: PLATFORMIO_AUTH_TOKEN: ${{ secrets.PLATFORMIO_AUTH_TOKEN }} jobs: - release: - name: Prepare a new release + wait_for_checks: + if: ${{ github.event_name != 'workflow_dispatch' }} + strategy: + matrix: + req_workflow: + [ + verify_library_structure.yaml, + build_examples.yaml, + build_documentation.yaml, + ] + name: Wait for Checks to complete runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set environment variable for current library version - run: | - echo "::debug::Get the current version number" - VER=$(cat VERSION) - ZIP_FILE="ModularSensors_Dependencies_${VER}" - echo "VERSION=$VER" >> $GITHUB_ENV - echo "ZIP_NAME=$ZIP_FILE" >> $GITHUB_ENV - - - name: Set up python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Install PlatformIO - run: | - python -m pip install --upgrade pip - pip install --upgrade platformio - - # Install *all* the libraries! - - name: Install the libraries - run: | - chmod +x continuous_integration/install-deps-platformio.sh - sh continuous_integration/install-deps-platformio.sh - - - name: Install ModularSensors from the master branch - run: | - pio pkg install -g -l https://github.com/EnviroDIY/ModularSensors - - # Uninstall graphics libraries from Adafruit - - name: Uninstall Adafruit GFX Library library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit GFX Library" - pio pkg uninstall -g -l "adafruit/Adafruit GFX Library" - - - name: Uninstall Adafruit NeoPixel library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit NeoPixel" - pio pkg uninstall -g -l "adafruit/Adafruit NeoPixel" - - - name: Uninstall Adafruit SSD1306 library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit SSD1306" - pio pkg uninstall -g -l "adafruit/Adafruit SSD1306" - - - name: Uninstall Adafruit ADXL343 library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit ADXL343" - pio pkg uninstall -g -l "adafruit/Adafruit ADXL343" - - - name: Uninstall Adafruit STMPE610 library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit STMPE610" - pio pkg uninstall -g -l "adafruit/Adafruit STMPE610" - - - name: Uninstall Adafruit TouchScreen library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit TouchScreen" - pio pkg uninstall -g -l "adafruit/Adafruit TouchScreen" - - - name: Uninstall Adafruit ILI9341 library - continue-on-error: true - run: | - echo "::debug::Removing Adafruit ILI9341" - pio pkg uninstall -g -l "adafruit/Adafruit ILI9341" - - # zip up all the installed libraries - # need to cd into the pio directory so we don't get extra junk directories - - name: Zip libraries - run: | - echo "::debug::Listing global libraries" - pio pkg list -g -v --only-libraries - echo "::debug::Zipping global libraries" - cd /home/runner/.platformio/ - zip ${{ env.ZIP_NAME }}.zip -r lib - mv ${{ env.ZIP_NAME }}.zip $GITHUB_WORKSPACE - cd $GITHUB_WORKSPACE - ls - - # Remove some extras from the zip - - name: Remove git files from the zip - continue-on-error: true - run: | - echo "::debug::Deleting extra files to decrease size of zip" - echo "::debug::Removing Git folders" - zip -d -q ${{ env.ZIP_NAME }} "*/.gitattributes" "*/.gitignore" "*/.gitmodules" "*/.github/*" "*.sh" "*/Doxyfile" "*/.travis.yml" - - name: Remove other pdfs from the zip - continue-on-error: true - run: | - echo "::debug::Removing other pdfs" - zip -d -q libraries "*/doc/*.pdf" - - name: Remove TinyGSM extras from the zip - continue-on-error: true - run: | - echo "::debug::Removing TinyGSM extras" - zip -d -q libraries "*/TinyGSM/extras/*" - - name: Remove YosemitechModbus extras from the zip - continue-on-error: true - run: | - echo "::debug::Removing YosemitechModbus extras" - zip -d -q libraries "*/YosemitechModbus/doc/*" - - name: Remove SDFat extras from the zip - continue-on-error: true - run: | - echo "::debug::Removing SDFat extras" - zip -d -q libraries "*/SdFat/extras/*" - - - name: Get change log entry for release notes - id: changelog_reader - uses: mindsers/changelog-reader-action@v2 - with: - path: ChangeLog.md - version: ${{ env.VERSION }} - # validation_depth: 10 - - # I use the first line of the change log entry as the name, so read it here - # - name: Get release name - # id: get_release_name - # run: | - # release_name=$(echo ${{steps.changelog_reader.outputs.changes}} | cut -d '\n' -f 1) - # echo "release_name=release_name" >> $GITHUB_OUTPUT - - # Create a new release - - name: Create release - id: create_release - uses: softprops/action-gh-release@v2.0.5 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Wait on Workflow + uses: ArcticLampyrid/action-wait-for-workflow@v1.2.0 with: - tag_name: ${{ format('v{0}',env.VERSION) }} - # name: ${{ format('v{0} - {1}', env.VERSION, steps.get_release_name.outputs.release_name) }} - name: ${{ format('v{0}',env.VERSION) }} - draft: ${{ steps.changelog_reader.outputs.status == 'unreleased' }} - prerelease: ${{ steps.changelog_reader.outputs.status == 'prereleased' }} - body: ${{ steps.changelog_reader.outputs.changes }} - generate_release_notes: false - files: ${{ format('./{0}.zip', env.ZIP_NAME) }} - fail_on_unmatched_files: true + workflow: ${{ matrix.req_workflow }} + sha: ${{ github.sha || github.event.pull_request.head.sha || github.event.pull_request.head.ref }} # optional + allowed-conclusions: | + success + cancelled + skipped - # Publish the new release to the PlatformIO package manager - - name: Publish release to the PlatformIO package manager - id: publish-pio - run: pio package publish --owner envirodiy --non-interactive + release: + name: Prepare a new release + needs: [wait_for_checks] + if: | + always() && + (needs.wait_for_checks.result == 'success' || needs.wait_for_checks.result == 'skipped') + uses: EnviroDIY/workflows/.github/workflows/prepare_release.yaml@main + secrets: inherit + with: + library-manager: 'update' + library-compliance: 'strict' diff --git a/.github/workflows/verify_library_structure.yaml b/.github/workflows/verify_library_structure.yaml index 2d8aad016..bf9958771 100644 --- a/.github/workflows/verify_library_structure.yaml +++ b/.github/workflows/verify_library_structure.yaml @@ -8,91 +8,10 @@ concurrency: cancel-in-progress: true jobs: - pio_lint: - name: Verify library.json for PlatformIO - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Install PlatformIO - run: | - python -m pip install --upgrade pip - pip install --upgrade platformio - - - name: Run python script to verify structure of library.json for PlatformIO - id: validate_manifest - continue-on-error: true - run: | - python continuous_integration/validate_manifest.py 2>&1 | tee validate_manifest.log - result_code=${PIPESTATUS[0]} - manifest_errors=$(cat validate_manifest.log) - manifest_errors="${manifest_errors//'%'/'%25'}" - manifest_errors="${manifest_errors//$'\n'/'%0A'}" - manifest_errors="${manifest_errors//$'\r'/'%0D'}" - echo "manifest_errors=manifest_errors" >> $GITHUB_OUTPUT - echo "$(cat validate_manifest.log)" >> $GITHUB_STEP_SUMMARY - echo "Finished library.json manifest verification" - exit $result_code - - - name: Create commit comment - uses: peter-evans/commit-comment@v3 - if: steps.validate_manifest.outcome=='failure' - with: - body: | - Please correct errors in the library.json file! - ${{ steps.validate_manifest.outputs.manifest_errors }} - - - name: Fail if cannot verify json - id: verification_failure - if: steps.validate_manifest.outcome=='failure' - run: exit 1 - - arduino_lint: - name: Validate library structure for Arduino Library Manager inclusion - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" - - steps: - - uses: actions/checkout@v4 - - - name: Run Arduino-Lint to verify the library structure and syntax for the Arduino IDE - id: validate_library - continue-on-error: true - env: - ARDUINO_LINT_LIBRARY_MANAGER_INDEXING: true - uses: arduino/arduino-lint-action@v1 - with: - project-type: library - library-manager: submit - compliance: strict - verbose: true - report-file: arduino_lint.json - - - name: beautify_lint_output - id: beautify_output - run: | - python continuous_integration/beautify_arduino_lint_log.py - lint_errors=$(cat arduino_lint.md) - lint_errors="${lint_errors//'%'/'%25'}" - lint_errors="${lint_errors//$'\n'/'%0A'}" - lint_errors="${lint_errors//$'\r'/'%0D'}" - echo "lint_errors=lint_errors" >> $GITHUB_OUTPUT - echo "$(cat arduino_lint.md)" >> $GITHUB_STEP_SUMMARY - - - name: Create commit comment - uses: peter-evans/commit-comment@v3 - if: steps.validate_library.outcome=='failure' - with: - body: ${{ steps.beautify_output.outputs.lint_errors }} - - - name: Fail if cannot verify library structure - id: verification_failure - if: steps.validate_library.outcome=='failure' - run: exit 1 + verify_library_structure: + name: Validate library structure + if: ${{ ! contains(github.event.head_commit.message, 'ci skip') }} + uses: EnviroDIY/workflows/.github/workflows/verify_library_structure.yaml@main + with: + library-manager: 'update' + library-compliance: 'strict' diff --git a/.gitignore b/.gitignore index 9c278f49b..ec6909142 100644 --- a/.gitignore +++ b/.gitignore @@ -47,22 +47,22 @@ Network Trash Folder Temporary Items .apdisk +# Python +__pycache__/ + # PyCharm .idea/ -# Atom / PlatformIO -.pio -.pioenvs -.piolibdeps -.pio -.pio/libdeps -.pio/build +# Atom +.atomrc.cson + +# PlatformIO .pio/* .clang_complete .gcc-flags.json -.atomrc.cson lib/* include/* +boards/* /platformio.ini .sconsign.dblite @@ -80,21 +80,13 @@ YosemitechDO/ LongTermLogger/ barometric_correction/ 3G_Test/ - -__pycache__/ runDoxygen.bat docs/examples/* -output_doxygen.log -output_doxygen_run.log -output_mcss_run.log -output_mcss.log docs/examples.dox_x platformio_extra_envs.ini src/sensors/table.md cache -docs/output_copyFunctions.log -docs/output_documentExamples.log -docs/output_fixSectionsInXml.log +output_*.log examples/DRWI_Mayfly1_Wifi_5tm_ds18b20_1/DRWI_Mayfly1_Wifi_5tm_ds18b20_1.ino clang_format_all.bat arduino_lint.md @@ -109,6 +101,8 @@ continuous_integration_artifacts/* arduino_cli.log **/sensor_tests/* docs/Doxyfile.bak -continuous_integration/output_check_component_inclusion.log continuous_integration/platformio_ci_local.ini -pioScripts/install_shared_deps.py +runDoxygen_archive.bat +generateKeywords.bat +update_path.bat +pio_common_libdeps.ini diff --git a/continuous_integration/generate-documentation.sh b/continuous_integration/generate-documentation.sh deleted file mode 100644 index 5985eeaa1..000000000 --- a/continuous_integration/generate-documentation.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -# Makes the bash script print out every command before it is executed, except echo -trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG - -# Script modified from scripts by Jeroen de Bruijn, thephez, and Adafruit -# https://gist.github.com/vidavidorra/548ffbcdae99d752da02 -# https://github.com/thephez/doxygen-travis-build -# https://learn.adafruit.com/the-well-automated-arduino-library/travis-ci - -# Exit with nonzero exit code if anything fails -set -e - -cd $GITHUB_WORKSPACE/code_docs/m.css -echo "\n\e[32mUpdate the style sheets\e[0m" -cd $GITHUB_WORKSPACE/code_docs/m.css/css/EnviroDIY -python $GITHUB_WORKSPACE/code_docs/m.css/css/postprocess.py "m-EnviroDIY.css" -python $GITHUB_WORKSPACE/code_docs/m.css/css/postprocess.py "m-EnviroDIY.css" "m-documentation.css" -o "m-EnviroDIY+documentation.compiled.css" -python $GITHUB_WORKSPACE/code_docs/m.css/css/postprocess.py "m-EnviroDIY.css" "m-theme-EnviroDIY.css" "m-documentation.css" --no-import -o "m-EnviroDIY.documentation.compiled.css" -cp $GITHUB_WORKSPACE/code_docs/m.css/css/EnviroDIY/m-EnviroDIY+documentation.compiled.css $GITHUB_WORKSPACE/code_docs/ModularSensors/docs/css - -cd $GITHUB_WORKSPACE/code_docs/ModularSensors/docs - -# echo "\n\e[32mCreating dox files from example read-me files\e[0m" -# python documentExamples.py - -echo "\n\e[32mCurrent Doxygen version...\e[0m" -$GITHUB_WORKSPACE/doxygen-src/build/bin/doxygen -v 2>&1 - -# Redirect both stderr and stdout to the log file AND the console. -echo "\n\e[32mGenerating Doxygen code documentation...\e[0m" -$GITHUB_WORKSPACE/doxygen-src/build/bin/doxygen Doxyfile 2>&1 - -echo "\n\e[32mFixing errant xml section names in examples as generated by Doxygen...\e[0m" -python fixSectionsInXml.py - -# echo "\n\e[32mFixing copied function documentation in group documentation\e[0m" -# python fixFunctionsInGroups.py - -python $GITHUB_WORKSPACE/code_docs/m.css/documentation/doxygen.py "mcss-conf.py" --no-doxygen --output "$GITHUB_WORKSPACE/code_docs/ModularSensors/docs/output_mcss.log" --templates "$GITHUB_WORKSPACE/code_docs/m.css/documentation/templates/EnviroDIY" - -echo "\n\e[32mCopying function documentation\e[0m" -python copyFunctions.py diff --git a/continuous_integration/generate_job_matrix.py b/continuous_integration/generate_job_matrix.py index 495ee97ff..b8c12ebde 100644 --- a/continuous_integration/generate_job_matrix.py +++ b/continuous_integration/generate_job_matrix.py @@ -8,35 +8,54 @@ import re import os import copy +import requests + +# %% +# set verbose +use_verbose = False +if "RUNNER_DEBUG" in os.environ.keys() and os.environ["RUNNER_DEBUG"] == "1": + use_verbose = True + # %% # Some working directories + # The workspace directory if "GITHUB_WORKSPACE" in os.environ.keys(): workspace_dir = os.environ.get("GITHUB_WORKSPACE") else: - fileDir = os.path.dirname(os.path.realpath("__file__")) - workspace_dir = os.path.join(fileDir, "../") - workspace_dir = os.path.abspath(os.path.realpath(workspace_dir)) + workspace_dir = os.getcwd() +workspace_path = os.path.abspath(os.path.realpath(workspace_dir)) +print(f"Workspace Path: {workspace_path}") # The examples directory examples_dir = "./examples/" examples_path = os.path.join(workspace_dir, examples_dir) examples_path = os.path.abspath(os.path.realpath(examples_path)) +print(f"Examples Path: {examples_path}") # The continuous integration directory ci_dir = "./continuous_integration/" ci_path = os.path.join(workspace_dir, ci_dir) ci_path = os.path.abspath(os.path.realpath(ci_path)) +print(f"Continuous Integration Path: {ci_path}") +if not os.path.exists(ci_path): + print(f"Creating the directory for CI: {ci_path}") + os.makedirs(ci_path, exist_ok=True) # A directory of files to save and upload as artifacts to use in future jobs artifact_dir = os.path.join( os.path.join(workspace_dir, "continuous_integration_artifacts") ) +artifact_path = os.path.abspath(os.path.realpath(artifact_dir)) +print(f"Artifact Path: {artifact_path}") if not os.path.exists(artifact_dir): + print(f"Creating the directory for artifacts: {artifact_path}") os.makedirs(artifact_dir) compilers = ["Arduino CLI", "PlatformIO"] + + # %% # The locations of some important files @@ -46,6 +65,18 @@ os.path.join(examples_path, menu_example_name), menu_example_name + ".ino" ) + +# %% +# Pull files to convert between boards and platforms and FQBNs +response = requests.get( + "https://raw.githubusercontent.com/EnviroDIY/workflows/main/scripts/platformio_to_arduino_boards.json" +) +with open(os.path.join(ci_path, "platformio_to_arduino_boards.json"), "wb") as f: + f.write(response.content) +# Translation between board names on PlatformIO and the Arduino CLI +with open(os.path.join(ci_path, "platformio_to_arduino_boards.json")) as f: + pio_to_acli = json.load(f) + # Find all of the non-menu examples non_menu_examples = [ f @@ -54,13 +85,30 @@ and f not in [".history", "logger_test", menu_example_name] ] -# Arduino CLI configurations +# %% +# read configurations based on existing files and environment variables + +# Arduino CLI configuration +# Always use the generic one from the shared workflow repository if "GITHUB_WORKSPACE" in os.environ.keys(): - arduino_cli_config = os.path.join(ci_dir, "arduino_cli.yaml") + arduino_cli_config = os.path.join(ci_path, "arduino_cli.yaml") + if not os.path.isfile(arduino_cli_config): + # download the default file + response = requests.get( + "https://raw.githubusercontent.com/EnviroDIY/workflows/main/scripts/arduino_cli.yaml" + ) + # copy to the CI directory + with open(os.path.join(ci_path, "arduino_cli.yaml"), "wb") as f: + f.write(response.content) + # also copy to the artifacts directory + shutil.copyfile( + os.path.join(ci_path, "arduino_cli.yaml"), + os.path.join(artifact_path, "arduino_cli.yaml"), + ) else: arduino_cli_config = os.path.join(ci_dir, "arduino_cli_local.yaml") -# PlatformIO configurations +# PlatformIO configuration pio_config_file = os.path.join(ci_path, "platformio.ini") pio_extra_config_file = os.path.join(ci_path, "platformio_extra_flags.ini") pio_config = ProjectConfig(pio_config_file) @@ -88,33 +136,39 @@ def get_example_filepath(subfolder_name): def create_arduino_cli_command(pio_env_name: str, code_subfolder: str) -> str: - arduino_command_arguments = [ + arduino_command_args = [ "arduino-cli", "compile", - # "--verbose", + ] + if use_verbose: + arduino_command_args += ["--verbose"] + arduino_command_args += [ "--warnings", "more", "--config-file", - arduino_cli_config, + f'"{arduino_cli_config}"', "--format", "text", "--fqbn", pio_to_acli[pio_config.get("env:{}".format(pio_env_name), "board")]["fqbn"], - os.path.join(examples_path, code_subfolder), + f'"{os.path.join(examples_path, code_subfolder)}"', ] - return " ".join(arduino_command_arguments) + return " ".join(arduino_command_args) def create_pio_ci_command(pio_env_file: str, pio_env: str, code_subfolder: str) -> str: pio_command_args = [ "pio", "ci", - # "--verbose", + ] + if use_verbose: + pio_command_args += ["--verbose"] + pio_command_args += [ "--project-conf", - pio_env_file, + f'"{pio_env_file}"', "--environment", pio_env, - os.path.join(examples_path, code_subfolder), + f'"{os.path.join(examples_path, code_subfolder)}"', ] return " ".join(pio_command_args) @@ -134,7 +188,7 @@ def add_log_to_command(command: str, group_title: str) -> List: ) command_list.append("echo ::endgroup::") command_list.append( - 'if [ "$result_code" -eq "0" ]; then echo -e "\e[32m{title} successfully compiled\e[0m"; else echo -e "\e[31m{title} failed to compile\e[0m"; fi'.format( + 'if [ "$result_code" -eq "0" ]; then echo -e "\\e[32m{title} successfully compiled\\e[0m"; else echo -e "\\e[31m{title} failed to compile\\e[0m"; fi'.format( title=group_title ) ) @@ -247,7 +301,7 @@ def modify_example_filename(example_subfolder, in_file_defines): preped_folder_name = "{}_{}".format(example_subfolder, suffix).replace( "_a_la_carte", "" ) - prepped_ex_folder = os.path.join(artifact_dir, preped_folder_name) + prepped_ex_folder = os.path.join(artifact_path, preped_folder_name) prepped_ex_file = os.path.join(prepped_ex_folder, preped_folder_name + ".ino") return prepped_ex_folder, prepped_ex_file @@ -296,7 +350,7 @@ def extend_pio_config(added_envs): new_config = copy.deepcopy(pio_config) new_config_path = os.path.join( - artifact_dir, "test_ci_" + "_".join(added_envs) + ".ini" + artifact_path, "test_ci_" + "_".join(added_envs) + ".ini" ) for added_env in added_envs: @@ -658,17 +712,23 @@ def extend_pio_config(added_envs): # Convert commands in the matrix into bash scripts for matrix_job in arduino_job_matrix + pio_job_matrix: bash_file_name = matrix_job["job_name"].replace(" ", "") + ".sh" - bash_out = open(os.path.join(artifact_dir, bash_file_name), "w+") + print(f"Writing bash file to {os.path.join(artifact_path, bash_file_name)}") + bash_out = open(os.path.join(artifact_path, bash_file_name), "w+") bash_out.write("#!/bin/bash\n\n") bash_out.write( - "# Makes the bash script print out every command before it is executed, except echo\n" - ) - bash_out.write( - "trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG\n\n" + """ +set -e # Exit with nonzero exit code if anything fails +if [ "$RUNNER_DEBUG" = "1" ]; then + echo "Enabling debugging!" + set -v # Prints shell input lines as they are read. + set -x # Print command traces before executing command. +fi + +""" ) bash_out.write(matrix_job["command"]) bash_out.close() - matrix_job["script"] = os.path.join(artifact_dir, bash_file_name) + matrix_job["script"] = os.path.join(artifact_path, bash_file_name) # Remove the command from the dictionaries before outputting them for items in arduino_job_matrix + pio_job_matrix: diff --git a/continuous_integration/install-deps-arduino-cli.sh b/continuous_integration/install-deps-arduino-cli.sh deleted file mode 100644 index 61ba26a4b..000000000 --- a/continuous_integration/install-deps-arduino-cli.sh +++ /dev/null @@ -1,159 +0,0 @@ -#!/bin/bash - -# Makes the bash script print out every command before it is executed, except echo -trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG - -# Exit with nonzero exit code if anything fails -set -e - -echo "\n\e[32mCurrent Arduino CLI version:\e[0m" -arduino-cli version - -echo "::group::Installing Platforms and Frameworks" -echo "\n\e[32mUpdating the core index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core update-index - -echo "\n\e[32mInstalling the Arduino AVR Core\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core install arduino:avr - -echo "\n\e[32mInstalling the EnviroDIY AVR Core\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core install EnviroDIY:avr - -echo "\n\e[32mInstalling the Arduino SAMD Core\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core install arduino:samd - -echo "\n\e[32mInstalling the Adafruit SAMD Core\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core install adafruit:samd - -echo "\n\e[32mUpdating the core index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core update-index - -echo "\n\e[32mUpgrading all cores\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core upgrade - -echo "\n\e[32mCurrently installed cores:\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml core list -echo "::endgroup::" - - -echo "::group::Installing Libraries" -echo "\n\e[32mUpdating the library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib update-index - -echo "\n\e[32mInstalling EnviroDIY DS3231 library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install EnviroDIY_DS3231 - -echo "\n\e[32mInstalling RTCZero library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install RTCZero - -echo "\n\e[32mInstalling EnableInterrupt library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install EnableInterrupt - -echo "\n\e[32mInstalling SdFat library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install SdFat - -echo "\n\e[32mInstalling TinyGSM library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install TinyGSM - -echo "\n\e[32mInstalling PubSubClient library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install PubSubClient - -echo "\n\e[32mInstalling Adafruit BusIO library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install "Adafruit BusIO" - -echo "\n\e[32mInstalling Adafruit Unified Sensor library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install "Adafruit Unified Sensor" - -echo "\n\e[32mDownloading Soligen fork of Adafruit_ADS1X15 as a zip" -# Soligen fork needs to be manually unzipped and moved because the CLI chokes on the library name not matching the h file -curl -L --retry 15 --retry-delay 0 https://github.com/soligen2010/Adafruit_ADS1X15/archive/master.zip --create-dirs -o home/arduino/downloads/Adafruit_ADS1X15.zip -echo "\e[32mDecompressing Adafruit_ADS1X15\e[0m" -unzip -q -o home/arduino/downloads/Adafruit_ADS1X15.zip -d home/arduino/downloads/ -echo "\e[32mMoving Adafruit_ADS1X15 to the libraries folder\e[0m" -mkdir -p home/arduino/user/libraries/Adafruit_ADS1X15 -mv home/arduino/downloads/Adafruit_ADS1X15-master/* home/arduino/user/libraries/Adafruit_ADS1X15 - -echo "\n\e[32mInstalling Adafruit AM2315 library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install "Adafruit AM2315" - -echo "\n\e[32mInstalling Adafruit BME280 Library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install "Adafruit BME280 Library" - -echo "\n\e[32mInstalling DHT sensor library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install "DHT sensor library" - -echo "\n\e[32mInstalling Adafruit INA219 library from Arduino library index - excluding dependencies\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install "Adafruit INA219" --no-deps - -echo "\n\e[32mInstalling Adafruit MPL115A2 library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install "Adafruit MPL115A2" - -echo "\n\e[32mInstalling Adafruit SHT4x Library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install "Adafruit SHT4x Library" - -echo "\n\e[32mInstalling Martin Lindupp's BMP388 Library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install "BMP388_DEV" - -echo "\n\e[32mInstalling OneWire library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install OneWire - -echo "\n\e[32mInstalling DallasTemperature library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install DallasTemperature - -echo "\n\e[32mDownloading External Interrupt version of the SDI-12 library as a zip\e[0m" -# The "external interrupt" version needs to be installed from a zip because the Arduino CLI cannot pull from a branch -curl -L --retry 15 --retry-delay 0 https://github.com/EnviroDIY/Arduino-SDI-12/archive/refs/heads/ExtInts.zip --create-dirs -o home/arduino/downloads/EnviroDIY_SDI12_ExtInts.zip -echo "\e[32mDecompressing EnviroDIY_SDI12_ExtInts\e[0m" -unzip -q -o home/arduino/downloads/EnviroDIY_SDI12_ExtInts.zip -d home/arduino/downloads/ -echo "\e[32mMoving EnviroDIY_SDI12_ExtInts to the libraries folder\e[0m" -mkdir -p home/arduino/user/libraries/EnviroDIY_SDI12_ExtInts -mv home/arduino/downloads/Arduino-SDI-12-ExtInts/* home/arduino/user/libraries/EnviroDIY_SDI12_ExtInts - -echo "\n\e[32mInstalling NorthernWidget MS5803 library from GitHub\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install --git-url https://github.com/NorthernWidget/MS5803.git - -echo "\n\e[32mInstalling EnviroDIY Tally_Library from GitHub" -# NOTE: This only works because the DEV_I2C branch is the main branch of the EnviroDIY fork -# The Arduino CLI can only install from whatever is assigned as the default branch on GitHub -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install --git-url https://github.com/EnviroDIY/Tally_Library.git - -echo "\n\e[32mInstalling EnviroDIY SensorModbusMaster library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install SensorModbusMaster - -echo "\n\e[32mInstalling EnviroDIY KellerModbus library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install KellerModbus - -echo "\n\e[32mInstalling EnviroDIY YosemitechModbus library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install YosemitechModbus - -echo "\n\e[32mInstalling EnviroDIY GropointModbus library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install GropointModbus - -echo "\n\e[32mInstalling StreamDebugger library from Arduino library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install StreamDebugger - -echo "\n\e[32mInstalling AltSoftSerial library from GitHub\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install --git-url https://github.com/PaulStoffregen/AltSoftSerial.git - -echo "\n\e[32mInstalling SoftwareWire library from GitHub\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install --git-url https://github.com/Testato/SoftwareWire.git#v1.5.1 - -echo "\n\e[32mInstalling NeoSWSerial library from GitHub\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib install --git-url https://github.com/SRGDamia1/NeoSWSerial.git - -echo "\n\e[32mDownloading SoftwareSerial with External Interrupts as a zip\e[0m" -# SoftwareSerial with External Interrupts needs to be manually unzipped and moved because the CLI chokes on the library name not matching the h file -curl -L --retry 15 --retry-delay 0 https://github.com/EnviroDIY/SoftwareSerial_ExternalInts/archive/master.zip --create-dirs -o home/arduino/downloads/SoftwareSerial_ExternalInts.zip -echo "\e[32mDecompressing SoftwareSerial_ExternalInts\e[0m" -unzip -q -o home/arduino/downloads/SoftwareSerial_ExternalInts.zip -d home/arduino/downloads/ -echo "\e[32mMoving SoftwareSerial_ExternalInts to the libraries folder\e[0m" -mkdir -p home/arduino/user/libraries/SoftwareSerial_ExternalInts -mv home/arduino/downloads/SoftwareSerial_ExtInts-master/* home/arduino/user/libraries/SoftwareSerial_ExternalInts -echo "::endgroup::" - - -echo "::group::Current globally installed packages" -echo "\n\e[32mCurrently installed libraries:\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib update-index -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib list -echo "::endgroup::" diff --git a/continuous_integration/install-deps-platformio.sh b/continuous_integration/install-deps-platformio.sh deleted file mode 100644 index 22219218e..000000000 --- a/continuous_integration/install-deps-platformio.sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/bin/bash - -# Makes the bash script print out every command before it is executed, except echo -trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG - -# Exit with nonzero exit code if anything fails -set -e - -echo "::group::Installing Platforms and Frameworks" -echo "\e[32mInstalling Atmel AVR platforms \e[0m" -pio pkg install -g --platform atmelavr -pio pkg install -g --tool framework-arduino-avr -pio pkg install -g --tool tool-avrdude -pio pkg install -g --tool toolchain-atmelavr - -echo "\e[32mInstalling Atmel AVR framework \e[0m" -pio pkg install -g --platform atmelmegaavr -pio pkg install -g --tool framework-arduino-megaavr - -echo "\e[32mInstalling Atmel SAM platform \e[0m" -pio pkg install -g --platform atmelsam - -echo "\e[32mInstalling Atmel SAM framework \e[0m" -pio pkg install -g --tool framework-arduino-samd -pio pkg install -g --tool framework-arduino-samd-adafruit -pio pkg install -g --tool framework-arduino-samd-sodaq -pio pkg install -g --tool framework-cmsis -pio pkg install -g --tool framework-cmsis-atmel -pio pkg install -g --tool tool-bossac -pio pkg install -g --tool toolchain-gccarmnoneeabi -echo "::endgroup::" - - -echo "::group::Installing Libraries" -echo "\e[32m\nCurrently installed packages:\e[0m" -pio pkg list -g -v - -echo "\e[32mInstalling envirodiy/EnviroDIY_DS3231\e[0m" -pio pkg install -g --library envirodiy/EnviroDIY_DS3231 - -echo "\e[32mInstalling arduino-libraries/RTCZero\e[0m" -pio pkg install -g --library arduino-libraries/RTCZero - -echo "\e[32mInstalling greygnome/EnableInterrupt\e[0m" -pio pkg install -g --library greygnome/EnableInterrupt - -echo "\e[32mInstalling greiman/SdFat\e[0m" -pio pkg install -g --library greiman/SdFat - -echo "\e[32mInstalling vshymanskyy/TinyGSM\e[0m" -pio pkg install -g --library vshymanskyy/TinyGSM - -echo "\e[32mInstalling knolleary/PubSubClient\e[0m" -pio pkg install -g --library knolleary/PubSubClient - -echo "\e[32mInstalling adafruit/'Adafruit BusIO'\e[0m" -pio pkg install -g --library adafruit/'Adafruit BusIO' - -echo "\e[32mInstalling adafruit/'Adafruit Unified Sensor'\e[0m" -pio pkg install -g --library adafruit/'Adafruit Unified Sensor' - -echo "\e[32mInstalling https://github.com/soligen2010/Adafruit_ADS1X15.git\e[0m" -pio pkg install -g --library https://github.com/soligen2010/Adafruit_ADS1X15.git - -echo "\e[32mInstalling adafruit/'Adafruit AM2315'\e[0m" -pio pkg install -g --library adafruit/'Adafruit AM2315' - -echo "\e[32mInstalling adafruit/'Adafruit BME280 Library'\e[0m" -pio pkg install -g --library adafruit/'Adafruit BME280 Library' - -echo "\e[32mInstalling adafruit/'DHT sensor library'\e[0m" -pio pkg install -g --library adafruit/'DHT sensor library' - -echo "\e[32mInstalling adafruit/'Adafruit INA219'\e[0m" -pio pkg install -g --library adafruit/'Adafruit INA219' - -echo "\e[32mInstalling adafruit/'Adafruit MPL115A2'\e[0m" -pio pkg install -g --library adafruit/'Adafruit MPL115A2' - -echo "\e[32mInstalling adafruit/'Adafruit SHT'\e[0m" -pio pkg install -g --library adafruit/'Adafruit SHT4x Library' - -echo "\e[32mInstalling Martin Lindupp's BMP388 Library\e[0m" -pio pkg install -g --library MartinL1/BMP388_DEV - -echo "\e[32mInstalling paulstoffregen/OneWire\e[0m" -pio pkg install -g --library paulstoffregen/OneWire - -echo "\e[32mInstalling milesburton/DallasTemperature\e[0m" -pio pkg install -g --library milesburton/DallasTemperature - -echo "\e[32mInstalling envirodiy/SDI-12\e[0m" -pio pkg install -g --library envirodiy/SDI-12 - -echo "\e[32mInstalling northernwidget/MS5803\e[0m" -pio pkg install -g --library northernwidget/MS5803 - -echo "\e[32mInstalling https://github.com/EnviroDIY/Tally_Library.git#Dev_I2C\e[0m" -pio pkg install -g --library https://github.com/EnviroDIY/Tally_Library.git#Dev_I2C - -echo "\e[32mInstalling envirodiy/SensorModbusMaster\e[0m" -pio pkg install -g --library envirodiy/SensorModbusMaster - -echo "\e[32mInstalling envirodiy/KellerModbus\e[0m" -pio pkg install -g --library envirodiy/KellerModbus - -echo "\e[32mInstalling envirodiy/YosemitechModbus\e[0m" -pio pkg install -g --library envirodiy/YosemitechModbus - -echo "\e[32mInstalling envirodiy/GroPointModbus\e[0m" -pio pkg install -g --library envirodiy/GroPointModbus - -echo "\e[32mInstalling vshymanskyy/StreamDebugger\e[0m" -pio pkg install -g --library vshymanskyy/StreamDebugger - -echo "\e[32mInstalling https://github.com/PaulStoffregen/AltSoftSerial.git\e[0m" -pio pkg install -g --library https://github.com/PaulStoffregen/AltSoftSerial.git - -echo "\e[32mInstalling https://github.com/Testato/SoftwareWire.git#v1.5.1\e[0m" -pio pkg install -g --library https://github.com/Testato/SoftwareWire.git#v1.5.1 - -echo "\e[32mInstalling https://github.com/SRGDamia1/NeoSWSerial.git\e[0m" -pio pkg install -g --library https://github.com/SRGDamia1/NeoSWSerial.git - -echo "\e[32mInstalling https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git\e[0m" -pio pkg install -g --library https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git -echo "::endgroup::" - - -echo "::group::Current globally installed packages" -echo "\e[32m\nCurrently installed packages:\e[0m" -pio pkg list -g -v -echo "::endgroup::" diff --git a/continuous_integration/install-test-version-arduino-cli.sh b/continuous_integration/install-test-version-arduino-cli.sh deleted file mode 100644 index 74ac0f883..000000000 --- a/continuous_integration/install-test-version-arduino-cli.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -# Makes the bash script print out every command before it is executed, except echo -trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG - -# Exit with nonzero exit code if anything fails -set -e - -echo "\n\e[32mCurrent Arduino CLI version:\e[0m" -arduino-cli version - -echo "\n\e[32mDeleting any archived zips\e[0m" -rm -f home/arduino/downloads/ModularSensors.zip - -echo "\n\e[32mDownloading library zip from ${LIBRARY_INSTALL_ZIP}\e[0m" -curl -L --retry 15 --retry-delay 0 ${LIBRARY_INSTALL_ZIP} --create-dirs -o home/arduino/downloads/ModularSensors.zip - -echo "\n\e[32mUnzipping the library\e[0m" -unzip -o home/arduino/downloads/ModularSensors.zip -d home/arduino/downloads/ -x "*.git/*" "continuous_integration/*" "docs/*" "examples/*" - -echo "\n\e[32mEnsuring no old directories exist\e[0m" -rm -r -f home/arduino/user/libraries/ModularSensors - -echo "\n\e[32mCreating a new directory for the testing version of Modular sensors\e[0m" -mkdir -p home/arduino/user/libraries/ModularSensors - -echo "\n\e[32mMoving the unzipped library to the new directory\e[0m" -if [ -z "${GITHUB_HEAD_REF}" ]; then - echo "\n\e[36mExpected unzipped directory name (from commit SHA): home/arduino/downloads/ModularSensors-${GITHUB_SHA}\e[0m" - mv home/arduino/downloads/ModularSensors-${GITHUB_SHA}/* home/arduino/user/libraries/ModularSensors -else - INTERNAL_ZIP_NAME=$(echo "${GITHUB_HEAD_REF}" | sed -e 's/\//-/g') - echo "\n\e[36mExpected unzipped directory name (from head of ${GITHUB_HEAD_REF}): home/arduino/downloads/ModularSensors-${SAVED_ZIP_NAME}\e[0m" - mv home/arduino/downloads/ModularSensors-${INTERNAL_ZIP_NAME}/* home/arduino/user/libraries/ModularSensors -fi - -echo "\n\e[32mUpdating the library index\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib update-index - -echo "\n\e[32mListing libraries detected by the Arduino CLI\e[0m" -arduino-cli --config-file continuous_integration/arduino_cli.yaml lib list - -echo "\n\e[32mListing the contents of the Arduino library directory\e[0m" -ls home/arduino/user/libraries diff --git a/docs/Doxyfile b/docs/Doxyfile index 840f599d3..f6ceb512d 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1,7 +1,7 @@ -# Doxyfile 1.9.6 +# Doxyfile 1.12.0 # This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. +# Doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. @@ -15,10 +15,10 @@ # # Note: # -# Use doxygen to compare the used configuration file with the template +# Use Doxygen to compare the used configuration file with the template # configuration file: # doxygen -x [configFile] -# Use doxygen to compare the used configuration file with the template +# Use Doxygen to compare the used configuration file with the template # configuration file without replacing the environment variables or CMake type # replacement variables: # doxygen -x_noenv [configFile] @@ -63,17 +63,23 @@ PROJECT_BRIEF = "An Arduino library to give environmental sensors a com PROJECT_LOGO = ModularSensors_ubuntu_264x55.png +# With the PROJECT_ICON tag one can specify an icon that is included in the tabs +# when the HTML document is shown. Doxygen will copy the logo to the output +# directory. + +PROJECT_ICON = + # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If +# entered, it will be relative to the location where Doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = ../../ModularSensorsDoxygen -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# If the CREATE_SUBDIRS tag is set to YES then Doxygen will create up to 4096 # sub-directories (in 2 levels) under the output directory of each output format # and will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where +# option can be useful when feeding Doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to # control the number of sub-directories. @@ -92,7 +98,7 @@ CREATE_SUBDIRS = NO CREATE_SUBDIRS_LEVEL = 8 -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# If the ALLOW_UNICODE_NAMES tag is set to YES, Doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. @@ -101,7 +107,7 @@ CREATE_SUBDIRS_LEVEL = 8 ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this +# documentation generated by Doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, # Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English @@ -115,14 +121,14 @@ ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# If the BRIEF_MEMBER_DESC tag is set to YES, Doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# If the REPEAT_BRIEF tag is set to YES, Doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the @@ -153,13 +159,13 @@ ABBREVIATE_BRIEF = "The $name class" \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief +# Doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# If the INLINE_INHERITED_MEMB tag is set to YES, Doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. @@ -167,7 +173,7 @@ ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# If the FULL_PATH_NAMES tag is set to YES, Doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. @@ -177,11 +183,11 @@ FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to +# If left blank the directory from which Doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. +# will be relative from the directory where Doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = .. @@ -195,14 +201,14 @@ STRIP_FROM_PATH = .. STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# If the SHORT_NAMES tag is set to YES, Doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief @@ -211,17 +217,17 @@ SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO -# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# If the JAVADOC_BANNER tag is set to YES then Doxygen will interpret a line # such as # /*************** # as being the beginning of a Javadoc-style comment "banner". If set to NO, the # Javadoc-style will behave just like regular comments and it will not be -# interpreted by doxygen. +# interpreted by Doxygen. # The default value is: NO. JAVADOC_BANNER = NO -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) @@ -229,7 +235,7 @@ JAVADOC_BANNER = NO QT_AUTOBRIEF = NO -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this @@ -241,10 +247,10 @@ QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO -# By default Python docstrings are displayed as preformatted text and doxygen's +# By default Python docstrings are displayed as preformatted text and Doxygen's # special commands cannot be used. By setting PYTHON_DOCSTRING to NO the -# doxygen's special commands can be used and the contents of the docstring -# documentation blocks is shown as doxygen documentation. +# Doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as Doxygen documentation. # The default value is: YES. PYTHON_DOCSTRING = YES @@ -255,7 +261,7 @@ PYTHON_DOCSTRING = YES INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# If the SEPARATE_MEMBER_PAGES tag is set to YES then Doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. @@ -342,30 +348,30 @@ OPTIMIZE_OUTPUT_SLICE = NO # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# language is one of the parsers supported by Doxygen: IDL, Java, JavaScript, # Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, # VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: # FortranFree, unknown formatted Fortran: Fortran. In the later case the parser # tries to guess whether the code is fixed or free formatted code, this is the -# default for Fortran type files). For instance to make doxygen treat .inc files +# default for Fortran type files). For instance to make Doxygen treat .inc files # as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. When specifying no_extension you should add +# the files are not read by Doxygen. When specifying no_extension you should add # * to the FILE_PATTERNS. # # Note see also the list of default file extension mappings. EXTENSION_MAPPING = ino=C++ -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# If the MARKDOWN_SUPPORT tag is enabled then Doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See https://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# The output of markdown processing is further processed by Doxygen, so you can +# mix Doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. @@ -375,12 +381,23 @@ MARKDOWN_SUPPORT = YES # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 5. +# Minimum value: 0, maximum value: 99, default value: 6. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 10 -# When enabled doxygen tries to link words that correspond to documented +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0 and GITHUB use the lower case version of title +# with any whitespace replaced by '-' and punctuation characters removed. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = GITHUB + +# When enabled Doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. @@ -390,10 +407,10 @@ AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and +# tag to YES in order to let Doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. +# versus func(std::string) {}). This also makes the inheritance and +# collaboration diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO @@ -405,16 +422,16 @@ BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. +# https://www.riverbankcomputing.com/software) sources only. Doxygen will parse +# them like normal C++ but will assume all classes use public instead of private +# inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. +# Doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. @@ -423,7 +440,7 @@ SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first +# tag is set to YES then Doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. @@ -481,18 +498,18 @@ TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The +# code, Doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# Doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest +# symbols. At the end of a run Doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 -# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use -# during processing. When set to 0 doxygen will based this on the number of +# The NUM_PROC_THREADS specifies the number of threads Doxygen is allowed to use +# during processing. When set to 0 Doxygen will based this on the number of # cores available in the system. You can set it explicitly to a value larger # than 0 to get more control over the balance between CPU load and processing # speed. At this moment only the input processing can be done using multiple @@ -504,11 +521,19 @@ LOOKUP_CACHE_SIZE = 0 NUM_PROC_THREADS = 1 +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = YES + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# If the EXTRACT_ALL tag is set to YES, Doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. @@ -574,7 +599,7 @@ EXTRACT_ANON_NSPACES = NO RESOLVE_UNNAMED_PARAMS = YES -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. @@ -582,7 +607,7 @@ RESOLVE_UNNAMED_PARAMS = YES HIDE_UNDOC_MEMBERS = NO -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option # will also hide undocumented C++ concepts if enabled. This option has no effect @@ -591,14 +616,14 @@ HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all friend # declarations. If set to NO, these declarations will be included in the # documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. @@ -612,7 +637,7 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO -# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# With the correct setting of option CASE_SENSE_NAMES Doxygen will better be # able to match the capabilities of the underlying filesystem. In case the # filesystem is case sensitive (i.e. it supports files in the same directory # whose names only differ in casing), the option must be set to YES to properly @@ -621,7 +646,7 @@ INTERNAL_DOCS = NO # output files written for symbols that only differ in casing, such as for two # classes, one named CLASS and the other named Class, and to also support # references to files without having to specify the exact matching casing. On -# Windows (including Cygwin) and MacOS, users should typically set this option +# Windows (including Cygwin) and macOS, users should typically set this option # to NO, whereas on Linux or other Unix flavors it should typically be set to # YES. # Possible values are: SYSTEM, NO and YES. @@ -629,14 +654,14 @@ INTERNAL_DOCS = NO CASE_SENSE_NAMES = NO -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# If the HIDE_SCOPE_NAMES tag is set to NO then Doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then Doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. @@ -649,7 +674,7 @@ HIDE_COMPOUND_REFERENCE= NO SHOW_HEADERFILE = YES -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# If the SHOW_INCLUDE_FILES tag is set to YES then Doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -662,7 +687,7 @@ SHOW_INCLUDE_FILES = YES SHOW_GROUPED_MEMB_INC = YES -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. @@ -674,14 +699,14 @@ FORCE_LOCAL_INCLUDES = NO INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# If the SORT_MEMBER_DOCS tag is set to YES then Doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = NO -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# If the SORT_BRIEF_DOCS tag is set to YES then Doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. @@ -689,7 +714,7 @@ SORT_MEMBER_DOCS = NO SORT_BRIEF_DOCS = NO -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then Doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. @@ -701,7 +726,7 @@ SORT_BRIEF_DOCS = NO SORT_MEMBERS_CTORS_1ST = NO -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# If the SORT_GROUP_NAMES tag is set to YES then Doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. @@ -718,11 +743,11 @@ SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = YES -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# If the STRICT_PROTO_MATCHING option is enabled and Doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# simple string match. By disabling STRICT_PROTO_MATCHING Doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. @@ -792,25 +817,25 @@ SHOW_FILES = YES SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from +# Doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file +# by Doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated +# by Doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can +# that represents Doxygen's defaults, run Doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. See also section "Changing the # layout of pages" for information. # -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# Note that if you run Doxygen from a directory containing a file called +# DoxygenLayout.xml, Doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = DoxygenLayout.xml @@ -825,19 +850,35 @@ LAYOUT_FILE = DoxygenLayout.xml CITE_BIB_FILES = +# The EXTERNAL_TOOL_PATH tag can be used to extend the search path (PATH +# environment variable) so that external tools such as latex and gs can be +# found. +# Note: Directories specified with EXTERNAL_TOOL_PATH are added in front of the +# path already specified by the PATH variable, and are added in the order +# specified. +# Note: This option is particularly useful for macOS version 14 (Sonoma) and +# higher, when running Doxygen from Doxywizard, because in this case any user- +# defined changes to the PATH are ignored. A typical example on macOS is to set +# EXTERNAL_TOOL_PATH = /Library/TeX/texbin /usr/local/bin +# together with the standard path, the full search path used by doxygen when +# launching external tools will then become +# PATH=/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin + +EXTERNAL_TOOL_PATH = + #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the +# standard output by Doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# generated to standard error (stderr) by Doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. @@ -845,14 +886,14 @@ QUIET = NO WARNINGS = YES -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# If the WARN_IF_UNDOCUMENTED tag is set to YES then Doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# If the WARN_IF_DOC_ERROR tag is set to YES, Doxygen will generate warnings for # potential errors in the documentation, such as documenting some parameters in # a documented function twice, or documenting parameters that don't exist or # using markup commands wrongly. @@ -860,8 +901,8 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES -# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete -# function parameter documentation. If set to NO, doxygen will accept that some +# If WARN_IF_INCOMPLETE_DOC is set to YES, Doxygen will warn about incomplete +# function parameter documentation. If set to NO, Doxygen will accept that some # parameters have no documentation without warning. # The default value is: YES. @@ -869,7 +910,7 @@ WARN_IF_INCOMPLETE_DOC = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong parameter +# value. If set to NO, Doxygen will only warn about wrong parameter # documentation, but not about the absence of documentation. If EXTRACT_ALL is # set to YES then this flag will automatically be disabled. See also # WARN_IF_INCOMPLETE_DOC @@ -877,24 +918,31 @@ WARN_IF_INCOMPLETE_DOC = YES WARN_NO_PARAMDOC = YES -# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about -# undocumented enumeration values. If set to NO, doxygen will accept +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, Doxygen will warn about +# undocumented enumeration values. If set to NO, Doxygen will accept # undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: NO. WARN_IF_UNDOC_ENUM_VAL = YES -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# If the WARN_AS_ERROR tag is set to YES then Doxygen will immediately stop when # a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS -# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but -# at the end of the doxygen process doxygen will return with a non-zero status. -# Possible values are: NO, YES and FAIL_ON_WARNINGS. +# then Doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the Doxygen process Doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then Doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined Doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. # The default value is: NO. WARN_AS_ERROR = FAIL_ON_WARNINGS -# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# The WARN_FORMAT tag determines the format of the warning messages that Doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will @@ -907,7 +955,7 @@ WARN_FORMAT = "$file:$line: $text" # In the $text part of the WARN_FORMAT command it is possible that a reference # to a more specific place is given. To make it easier to jump to this place -# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# (outside of Doxygen) the user can define a custom "cut" / "paste" string. # Example: # WARN_LINE_FORMAT = "'vi $file +$line'" # See also: WARN_FORMAT @@ -937,7 +985,7 @@ WARN_LOGFILE = output_doxygen.log INPUT = .. # This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# that Doxygen parses. Internally Doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: # https://www.gnu.org/software/libiconv/) for the list of possible encodings. @@ -947,12 +995,12 @@ INPUT = .. INPUT_ENCODING = UTF-8 # This tag can be used to specify the character encoding of the source files -# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# that Doxygen parses The INPUT_FILE_ENCODING tag can be used to specify # character encoding on a per file pattern basis. Doxygen will compare the file # name with each pattern and apply the encoding instead of the default # INPUT_ENCODING) if there is a match. The character encodings are a list of the -# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding -# "INPUT_ENCODING" for further information on supported encodings. +# form: pattern=encoding (like *.php=ISO-8859-1). +# See also: INPUT_ENCODING for further information on supported encodings. INPUT_FILE_ENCODING = @@ -962,17 +1010,17 @@ INPUT_FILE_ENCODING = # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. +# read by Doxygen. # # Note the list of default checked file patterns might differ from the list of # default file extension mappings. # -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, -# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C -# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, -# *.vhdl, *.ucf, *.qsf and *.ice. +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm, +# *.cpp, *.cppm, *.ccm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, +# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.ixx, *.l, *.cs, *.d, +# *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to +# be provided as Doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.c \ *.cc \ @@ -1004,7 +1052,7 @@ RECURSIVE = YES # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # -# Note that relative paths are relative to the directory from which doxygen is +# Note that relative paths are relative to the directory from which Doxygen is # run. EXCLUDE = ../src/ReadMe.md \ @@ -1034,9 +1082,6 @@ EXCLUDE_PATTERNS = # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # ANamespace::AClass, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = @@ -1073,7 +1118,7 @@ EXAMPLE_RECURSIVE = YES IMAGE_PATH = -# The INPUT_FILTER tag can be used to specify a program that doxygen should +# The INPUT_FILTER tag can be used to specify a program that Doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # @@ -1088,14 +1133,14 @@ IMAGE_PATH = # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # -# Note that doxygen will use the data processed and written to standard output +# Note that Doxygen will use the data processed and written to standard output # for further processing, therefore nothing else, like debug statements or used # commands (so in case of a Windows batch file always use @echo OFF), should be # written to standard output. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. +# properly processed by Doxygen. INPUT_FILTER = @@ -1108,7 +1153,7 @@ INPUT_FILTER = # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. +# properly processed by Doxygen. FILTER_PATTERNS = "*.md=python markdown_prefilter.py" @@ -1130,7 +1175,7 @@ FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. +# and want to reuse the introduction page also for the Doxygen output. USE_MDFILE_AS_MAINPAGE = README.md @@ -1157,12 +1202,13 @@ FORTRAN_COMMENT_AFTER = 72 SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. +# multi-line macros, enums or list initialized variables directly into the +# documentation. # The default value is: NO. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct Doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. @@ -1200,7 +1246,7 @@ REFERENCES_LINK_SOURCE = YES SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# point to the HTML generated by the htags(1) tool instead of Doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see https://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. @@ -1214,14 +1260,14 @@ SOURCE_TOOLTIPS = YES # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # -# The result: instead of the source browser generated by doxygen, the links to +# The result: instead of the source browser generated by Doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# If the VERBATIM_HEADERS tag is set the YES then Doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. @@ -1229,19 +1275,19 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# If the CLANG_ASSISTED_PARSING tag is set to YES then Doxygen will use the # clang parser (see: # http://clang.llvm.org/) for more accurate parsing at the cost of reduced # performance. This can be particularly helpful with template rich C++ code for -# which doxygen's built-in parser lacks the necessary type information. -# Note: The availability of this option depends on whether or not doxygen was +# which Doxygen's built-in parser lacks the necessary type information. +# Note: The availability of this option depends on whether or not Doxygen was # generated with the -Duse_libclang=ON option for CMake. # The default value is: NO. CLANG_ASSISTED_PARSING = NO # If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS -# tag is set to YES then doxygen will add the directory of each input to the +# tag is set to YES then Doxygen will add the directory of each input to the # include path. # The default value is: YES. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. @@ -1250,7 +1296,7 @@ CLANG_ADD_INC_PATHS = YES # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories +# the include paths will already be set by Doxygen for the files and directories # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. @@ -1264,7 +1310,7 @@ CLANG_OPTIONS = # specifying the -p option to a clang tool, such as clang-check. These options # will then be passed to the parser. Any options specified with CLANG_OPTIONS # will be added as well. -# Note: The availability of this option depends on whether or not doxygen was +# Note: The availability of this option depends on whether or not Doxygen was # generated with the -Duse_libclang=ON option for CMake. CLANG_DATABASE_PATH = @@ -1293,7 +1339,7 @@ IGNORE_PREFIX = # Configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# If the GENERATE_HTML tag is set to YES, Doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = NO @@ -1314,40 +1360,40 @@ HTML_OUTPUT = html HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a +# each generated HTML page. If the tag is left blank Doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. +# that Doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally +# for information on how to generate the default header that Doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description +# default header when upgrading to a newer version of Doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard +# generated HTML page. If the tag is left blank Doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. +# that Doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. +# the HTML output. If left blank Doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. +# sheet that Doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. @@ -1357,7 +1403,7 @@ HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. +# created by Doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. @@ -1385,11 +1431,11 @@ HTML_EXTRA_FILES = # The HTML_COLORSTYLE tag can be used to specify if the generated HTML output # should be rendered with a dark or light theme. -# Possible values are: LIGHT always generate light mode output, DARK always -# generate dark mode output, AUTO_LIGHT automatically set the mode according to -# the user preference, use light mode if no preference is set (the default), -# AUTO_DARK automatically set the mode according to the user preference, use -# dark mode if no preference is set and TOGGLE allow to user to switch between +# Possible values are: LIGHT always generates light mode output, DARK always +# generates dark mode output, AUTO_LIGHT automatically sets the mode according +# to the user preference, uses light mode if no preference is set (the default), +# AUTO_DARK automatically sets the mode according to the user preference, uses +# dark mode if no preference is set and TOGGLE allows a user to switch between # light and dark mode via a button. # The default value is: AUTO_LIGHT. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1426,15 +1472,6 @@ HTML_COLORSTYLE_SAT = 83 HTML_COLORSTYLE_GAMMA = 88 -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = YES - # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that # are dynamically created via JavaScript. If disabled, the navigation index will @@ -1454,6 +1491,33 @@ HTML_DYNAMIC_MENUS = YES HTML_DYNAMIC_SECTIONS = YES +# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be +# dynamically folded and expanded in the generated HTML source code. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_CODE_FOLDING = YES + +# If the HTML_COPY_CLIPBOARD tag is set to YES then Doxygen will show an icon in +# the top right corner of code and text fragments that allows the user to copy +# its content to the clipboard. Note this only works if supported by the browser +# and the web page is served via a secure context (see: +# https://www.w3.org/TR/secure-contexts/), i.e. using the https: or file: +# protocol. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COPY_CLIPBOARD = YES + +# Doxygen stores a couple of settings persistently in the browser (via e.g. +# cookies). By default these settings apply to all HTML pages generated by +# Doxygen across all projects. The HTML_PROJECT_COOKIE tag can be used to store +# the settings under a project specific key, such that the user preferences will +# be stored separately. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_PROJECT_COOKIE = + # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to @@ -1471,7 +1535,7 @@ HTML_INDEX_NUM_ENTRIES = 500 # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: # https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To -# create a documentation set, doxygen will generate a Makefile in the HTML +# create a documentation set, Doxygen will generate a Makefile in the HTML # output directory. Running make will produce the docset in that directory and # running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at @@ -1519,7 +1583,7 @@ DOCSET_PUBLISHER_ID = org.doxygen.Publisher DOCSET_PUBLISHER_NAME = Publisher -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# If the GENERATE_HTMLHELP tag is set to YES then Doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # on Windows. In the beginning of 2021 Microsoft took the original page, with @@ -1530,7 +1594,7 @@ DOCSET_PUBLISHER_NAME = Publisher # ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# generated by Doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for @@ -1550,7 +1614,7 @@ CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. +# Doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1584,6 +1648,16 @@ BINARY_TOC = NO TOC_EXPAND = NO +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help @@ -1642,7 +1716,7 @@ QHP_CUST_FILTER_ATTRS = QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location (absolute path -# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# including file name) of Qt's qhelpgenerator. If non-empty Doxygen will try to # run qhelpgenerator on the generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1687,7 +1761,7 @@ DISABLE_INDEX = NO # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine tune the look of the index (see "Fine-tuning the output"). As an -# example, the default style sheet generated by doxygen has an example that +# example, the default style sheet generated by Doxygen has an example that # shows how to put an image at the root of the tree instead of the PROJECT_NAME. # Since the tree basically has the same information as the tab index, you could # consider setting DISABLE_INDEX to YES when enabling this option. @@ -1709,7 +1783,7 @@ GENERATE_TREEVIEW = YES FULL_SIDEBAR = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. +# Doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. @@ -1718,6 +1792,12 @@ FULL_SIDEBAR = NO ENUM_VALUES_PER_LINE = 4 +# When the SHOW_ENUM_VALUES tag is set doxygen will show the specified +# enumeration values besides the enumeration mnemonics. +# The default value is: NO. + +SHOW_ENUM_VALUES = YES + # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. @@ -1725,21 +1805,21 @@ ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 200 -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# If the EXT_LINKS_IN_WINDOW option is set to YES, Doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO -# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# If the OBFUSCATE_EMAILS tag is set to YES, Doxygen will obfuscate email # addresses. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. OBFUSCATE_EMAILS = YES -# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# If the HTML_FORMULA_FORMAT option is set to svg, Doxygen will use the pdf2svg # tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see # https://inkscape.org) to generate formulas as SVG images instead of PNGs for # the HTML output. These images will generally look nicer at scaled resolutions. @@ -1752,7 +1832,7 @@ HTML_FORMULA_FORMAT = png # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML +# Doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1796,7 +1876,7 @@ MATHJAX_VERSION = MathJax_2 # Possible values are: HTML-CSS (which is slower, but has the best # compatibility. This is the name for Mathjax version 2, for MathJax version 3 # this will be translated into chtml), NativeMML (i.e. MathML. Only supported -# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# for MathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This # is the name for Mathjax version 3, for MathJax version 2 this will be # translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. @@ -1830,7 +1910,7 @@ MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2 MATHJAX_EXTENSIONS = -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# The MATHJAX_CODEFILE tag can be used to specify a file with JavaScript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: # http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an @@ -1839,12 +1919,12 @@ MATHJAX_EXTENSIONS = MATHJAX_CODEFILE = -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and +# When the SEARCHENGINE tag is enabled Doxygen will generate a search box for +# the HTML output. The underlying search engine uses JavaScript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then +# For large projects the JavaScript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically @@ -1863,7 +1943,7 @@ SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using JavaScript. There # are two flavors of web server based searching depending on the EXTERNAL_SEARCH -# setting. When disabled, doxygen will generate a PHP script for searching and +# setting. When disabled, Doxygen will generate a PHP script for searching and # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing # and searching needs to be provided by external tools. See the section # "External Indexing and Searching" for details. @@ -1872,7 +1952,7 @@ SEARCHENGINE = YES SERVER_BASED_SEARCH = NO -# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP +# When EXTERNAL_SEARCH tag is enabled Doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain the @@ -1917,7 +1997,7 @@ SEARCHDATA_FILE = searchdata.xml EXTERNAL_SEARCH_ID = -# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through Doxygen # projects other than the one defined by this configuration file, but that are # all added to the same external search index. Each project needs to have a # unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of @@ -1931,7 +2011,7 @@ EXTRA_SEARCH_MAPPINGS = # Configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. +# If the GENERATE_LATEX tag is set to YES, Doxygen will generate LaTeX output. # The default value is: YES. GENERATE_LATEX = NO @@ -1976,7 +2056,7 @@ MAKEINDEX_CMD_NAME = makeindex LATEX_MAKEINDEX_CMD = makeindex -# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX +# If the COMPACT_LATEX tag is set to YES, Doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -2007,15 +2087,15 @@ EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for # the generated LaTeX document. The header should contain everything until the -# first chapter. If it is left blank doxygen will generate a standard header. It +# first chapter. If it is left blank Doxygen will generate a standard header. It # is highly recommended to start with a default header using # doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty # and then modify the file new_header.tex. See also section "Doxygen usage" for -# information on how to generate the default header that doxygen normally uses. +# information on how to generate the default header that Doxygen normally uses. # # Note: Only use a user-defined header if you know what you are doing! # Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. The following +# default header when upgrading to a newer version of Doxygen. The following # commands have a special meaning inside the header (and footer): For a # description of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -2024,10 +2104,10 @@ LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for # the generated LaTeX document. The footer should contain everything after the -# last chapter. If it is left blank doxygen will generate a standard footer. See +# last chapter. If it is left blank Doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what # special commands can be used inside the footer. See also section "Doxygen -# usage" for information on how to generate the default footer that doxygen +# usage" for information on how to generate the default footer that Doxygen # normally uses. Note: Only use a user-defined footer if you know what you are # doing! # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -2036,7 +2116,7 @@ LATEX_FOOTER = # The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined # LaTeX style sheets that are included after the standard style sheets created -# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# by Doxygen. Using this option one can overrule certain style aspects. Doxygen # will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the @@ -2062,7 +2142,7 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES -# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as +# If the USE_PDFLATEX tag is set to YES, Doxygen will use the engine as # specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX # files. Set this option to YES, to get a higher quality PDF documentation. # @@ -2072,15 +2152,22 @@ PDF_HYPERLINKS = YES USE_PDFLATEX = YES -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode -# command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. +# The LATEX_BATCHMODE tag signals the behavior of LaTeX in case of an error. +# Possible values are: NO same as ERROR_STOP, YES same as BATCH, BATCH In batch +# mode nothing is printed on the terminal, errors are scrolled as if is +# hit at every error; missing files that TeX tries to input or request from +# keyboard input (\read on a not open input stream) cause the job to abort, +# NON_STOP In nonstop mode the diagnostic message will appear on the terminal, +# but there is no possibility of user interaction just like in batch mode, +# SCROLL In scroll mode, TeX will stop only for missing files to input or if +# keyboard input is necessary and ERROR_STOP In errorstop mode, TeX will stop at +# each error, asking for user intervention. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_BATCHMODE = NO -# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the +# If the LATEX_HIDE_INDICES tag is set to YES then Doxygen will not include the # index chapters (such as File Index, Compound Index, etc.) in the output. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -2095,14 +2182,6 @@ LATEX_HIDE_INDICES = NO LATEX_BIB_STYLE = plain -# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_TIMESTAMP = NO - # The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) # path from which the emoji images will be read. If a relative path is entered, # it will be relative to the LATEX_OUTPUT directory. If left blank the @@ -2115,7 +2194,7 @@ LATEX_EMOJI_DIRECTORY = # Configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The +# If the GENERATE_RTF tag is set to YES, Doxygen will generate RTF output. The # RTF output is optimized for Word 97 and may not look too pretty with other RTF # readers/editors. # The default value is: NO. @@ -2130,7 +2209,7 @@ GENERATE_RTF = NO RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF +# If the COMPACT_RTF tag is set to YES, Doxygen generates more compact RTF # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -2150,28 +2229,36 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's +# Load stylesheet definitions from file. Syntax is similar to Doxygen's # configuration file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. # # See also section "Doxygen usage" for information on how to generate the -# default style sheet that doxygen normally uses. +# default style sheet that Doxygen normally uses. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's configuration file. A template extensions file can be +# similar to Doxygen's configuration file. A template extensions file can be # generated using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_EXTENSIONS_FILE = +# The RTF_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the RTF_OUTPUT output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTRA_FILES = + #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for +# If the GENERATE_MAN tag is set to YES, Doxygen will generate man pages for # classes and files. # The default value is: NO. @@ -2202,7 +2289,7 @@ MAN_EXTENSION = .3 MAN_SUBDIR = -# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, then it # will generate one additional man file for each entity documented in the real # man page(s). These additional files only source the real man page, but without # them the man command would be unable to find the correct page. @@ -2215,7 +2302,7 @@ MAN_LINKS = NO # Configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that +# If the GENERATE_XML tag is set to YES, Doxygen will generate an XML file that # captures the structure of the code including all documentation. # The default value is: NO. @@ -2229,7 +2316,7 @@ GENERATE_XML = YES XML_OUTPUT = xml -# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program +# If the XML_PROGRAMLISTING tag is set to YES, Doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size # of the XML output. @@ -2238,7 +2325,7 @@ XML_OUTPUT = xml XML_PROGRAMLISTING = NO -# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, Doxygen will include # namespace members in file scope as well, matching the HTML output. # The default value is: NO. # This tag requires that the tag GENERATE_XML is set to YES. @@ -2249,7 +2336,7 @@ XML_NS_MEMB_FILE_SCOPE = YES # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- -# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files +# If the GENERATE_DOCBOOK tag is set to YES, Doxygen will generate Docbook files # that can be used to generate PDF. # The default value is: NO. @@ -2267,19 +2354,45 @@ DOCBOOK_OUTPUT = docbook # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# If the GENERATE_AUTOGEN_DEF tag is set to YES, Doxygen will generate an +# AutoGen Definitions (see https://autogen.sourceforge.net/) file that captures # the structure of the code including all documentation. Note that this feature # is still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to Sqlite3 output +#--------------------------------------------------------------------------- + +# If the GENERATE_SQLITE3 tag is set to YES Doxygen will generate a Sqlite3 +# database with symbols found by Doxygen stored in tables. +# The default value is: NO. + +GENERATE_SQLITE3 = NO + +# The SQLITE3_OUTPUT tag is used to specify where the Sqlite3 database will be +# put. If a relative path is entered the value of OUTPUT_DIRECTORY will be put +# in front of it. +# The default directory is: sqlite3. +# This tag requires that the tag GENERATE_SQLITE3 is set to YES. + +SQLITE3_OUTPUT = sqlite3 + +# The SQLITE3_RECREATE_DB tag is set to YES, the existing doxygen_sqlite3.db +# database file will be recreated with each Doxygen run. If set to NO, Doxygen +# will warn if a database file is already found and not modify it. +# The default value is: YES. +# This tag requires that the tag GENERATE_SQLITE3 is set to YES. + +SQLITE3_RECREATE_DB = YES + #--------------------------------------------------------------------------- # Configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module +# If the GENERATE_PERLMOD tag is set to YES, Doxygen will generate a Perl module # file that captures the structure of the code including all documentation. # # Note that this feature is still experimental and incomplete at the moment. @@ -2287,7 +2400,7 @@ GENERATE_AUTOGEN_DEF = NO GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary +# If the PERLMOD_LATEX tag is set to YES, Doxygen will generate the necessary # Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI # output from the Perl module output. # The default value is: NO. @@ -2317,13 +2430,13 @@ PERLMOD_MAKEVAR_PREFIX = # Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all +# If the ENABLE_PREPROCESSING tag is set to YES, Doxygen will evaluate all # C-preprocessor directives found in the sources and include files. # The default value is: YES. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# If the MACRO_EXPANSION tag is set to YES, Doxygen will expand all macro names # in the source code. If set to NO, only conditional compilation will be # performed. Macro expansion can be done in a controlled way by setting # EXPAND_ONLY_PREDEF to YES. @@ -2434,7 +2547,7 @@ EXPAND_AS_DEFINED = MS_MODEM_EXTRA_SETUP \ MS_PRINT_DEBUG_TIMER \ MAKE_VARIABLE_CLASS -# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will +# If the SKIP_FUNCTION_MACROS tag is set to YES then Doxygen's preprocessor will # remove all references to function-like macros that are alone on a line, have # an all uppercase name, and do not end with a semicolon. Such function macros # are typically used for boiler-plate code, and will confuse the parser if not @@ -2458,26 +2571,26 @@ SKIP_FUNCTION_MACROS = YES # section "Linking to external documentation" for more information about the use # of tag files. # Note: Each tag file must have a unique name (where the name does NOT include -# the path). If a tag file is not located in the directory in which doxygen is +# the path). If a tag file is not located in the directory in which Doxygen is # run, you must also specify the path to the tagfile here. TAGFILES = -# When a file name is specified after GENERATE_TAGFILE, doxygen will create a +# When a file name is specified after GENERATE_TAGFILE, Doxygen will create a # tag file that is based on the input files it reads. See section "Linking to # external documentation" for more information about the usage of tag files. GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES, all external class will be listed in -# the class index. If set to NO, only the inherited external classes will be -# listed. +# If the ALLEXTERNALS tag is set to YES, all external classes and namespaces +# will be listed in the class and namespace index. If set to NO, only the +# inherited external classes will be listed. # The default value is: NO. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will be +# in the topic index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. @@ -2491,33 +2604,26 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to diagram generator tools #--------------------------------------------------------------------------- -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. HIDE_UNDOC_RELATIONS = NO -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# If you set the HAVE_DOT tag to YES then Doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: -# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO # The default value is: NO. HAVE_DOT = YES -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed -# to run in parallel. When set to 0 doxygen will base this on the number of +# The DOT_NUM_THREADS specifies the number of dot invocations Doxygen is allowed +# to run in parallel. When set to 0 Doxygen will base this on the number of # processors available in the system. You can set it explicitly to a value # larger than 0 to get control over the balance between CPU load and processing # speed. @@ -2528,7 +2634,7 @@ DOT_NUM_THREADS = 0 # DOT_COMMON_ATTR is common attributes for nodes, edges and labels of # subgraphs. When you want a differently looking font in the dot files that -# doxygen generates you can specify fontname, fontcolor and fontsize attributes. +# Doxygen generates you can specify fontname, fontcolor and fontsize attributes. # For details please see Node, # Edge and Graph Attributes specification You need to make sure dot is able # to find the font, which can be done by putting it in a standard location or by @@ -2562,35 +2668,47 @@ DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" DOT_FONTPATH = -# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a -# graph for each documented class showing the direct and indirect inheritance -# relations. In case HAVE_DOT is set as well dot will be used to draw the graph, -# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set -# to TEXT the direct and indirect inheritance relations will be shown as texts / -# links. -# Possible values are: NO, YES, TEXT and GRAPH. +# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then Doxygen will +# generate a graph for each documented class showing the direct and indirect +# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and +# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case +# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the +# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used. +# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance +# relations will be shown as texts / links. Explicit enabling an inheritance +# graph or choosing a different representation for an inheritance graph of a +# specific class, can be accomplished by means of the command \inheritancegraph. +# Disabling an inheritance graph can be accomplished by means of the command +# \hideinheritancegraph. +# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN. # The default value is: YES. CLASS_GRAPH = YES -# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a +# If the COLLABORATION_GRAPH tag is set to YES then Doxygen will generate a # graph for each documented class showing the direct and indirect implementation # dependencies (inheritance, containment, and class references variables) of the -# class with other documented classes. +# class with other documented classes. Explicit enabling a collaboration graph, +# when COLLABORATION_GRAPH is set to NO, can be accomplished by means of the +# command \collaborationgraph. Disabling a collaboration graph can be +# accomplished by means of the command \hidecollaborationgraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. COLLABORATION_GRAPH = YES -# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. See also the chapter Grouping -# in the manual. +# If the GROUP_GRAPHS tag is set to YES then Doxygen will generate a graph for +# groups, showing the direct groups dependencies. Explicit enabling a group +# dependency graph, when GROUP_GRAPHS is set to NO, can be accomplished by means +# of the command \groupgraph. Disabling a directory graph can be accomplished by +# means of the command \hidegroupgraph. See also the chapter Grouping in the +# manual. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and +# If the UML_LOOK tag is set to YES, Doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. # The default value is: NO. @@ -2611,10 +2729,10 @@ UML_LOOK = NO UML_LIMIT_NUM_FIELDS = 10 -# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and +# If the DOT_UML_DETAILS tag is set to NO, Doxygen will show attributes and # methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS -# tag is set to YES, doxygen will add type and arguments for attributes and -# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen +# tag is set to YES, Doxygen will add type and arguments for attributes and +# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, Doxygen # will not generate fields with class member information in the UML graphs. The # class diagrams will look similar to the default class diagrams but using UML # notation for the relationships. @@ -2626,8 +2744,8 @@ DOT_UML_DETAILS = NO # The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters # to display on a single line. If the actual line length exceeds this threshold -# significantly it will wrapped across multiple lines. Some heuristics are apply -# to avoid ugly line breaks. +# significantly it will be wrapped across multiple lines. Some heuristics are +# applied to avoid ugly line breaks. # Minimum value: 0, maximum value: 1000, default value: 17. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2642,24 +2760,29 @@ DOT_WRAP_THRESHOLD = 17 TEMPLATE_RELATIONS = YES # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to -# YES then doxygen will generate a graph for each documented file showing the +# YES then Doxygen will generate a graph for each documented file showing the # direct and indirect include dependencies of the file with other documented -# files. +# files. Explicit enabling an include graph, when INCLUDE_GRAPH is is set to NO, +# can be accomplished by means of the command \includegraph. Disabling an +# include graph can be accomplished by means of the command \hideincludegraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. INCLUDE_GRAPH = YES # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are -# set to YES then doxygen will generate a graph for each documented file showing +# set to YES then Doxygen will generate a graph for each documented file showing # the direct and indirect include dependencies of the file with other documented -# files. +# files. Explicit enabling an included by graph, when INCLUDED_BY_GRAPH is set +# to NO, can be accomplished by means of the command \includedbygraph. Disabling +# an included by graph can be accomplished by means of the command +# \hideincludedbygraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. INCLUDED_BY_GRAPH = YES -# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# If the CALL_GRAPH tag is set to YES then Doxygen will generate a call # dependency graph for every global function or class method. # # Note that enabling this option will significantly increase the time of a run. @@ -2671,7 +2794,7 @@ INCLUDED_BY_GRAPH = YES CALL_GRAPH = YES -# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# If the CALLER_GRAPH tag is set to YES then Doxygen will generate a caller # dependency graph for every global function or class method. # # Note that enabling this option will significantly increase the time of a run. @@ -2683,17 +2806,20 @@ CALL_GRAPH = YES CALLER_GRAPH = YES -# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical +# If the GRAPHICAL_HIERARCHY tag is set to YES then Doxygen will graphical # hierarchy of all classes instead of a textual one. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the +# If the DIRECTORY_GRAPH tag is set to YES then Doxygen will show the # dependencies a directory has on other directories in a graphical way. The # dependency relations are determined by the #include relations between the -# files in the directories. +# files in the directories. Explicit enabling a directory graph, when +# DIRECTORY_GRAPH is set to NO, can be accomplished by means of the command +# \directorygraph. Disabling a directory graph can be accomplished by means of +# the command \hidedirectorygraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2709,7 +2835,7 @@ DIR_GRAPH_MAX_DEPTH = 5 # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: -# http://www.graphviz.org/)). +# https://www.graphviz.org/)). # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). @@ -2746,11 +2872,12 @@ DOT_PATH = DOTFILE_DIRS = -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). +# You can include diagrams made with dia in Doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. -MSCFILE_DIRS = +DIA_PATH = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile @@ -2758,7 +2885,7 @@ MSCFILE_DIRS = DIAFILE_DIRS = -# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# When using PlantUML, the PLANTUML_JAR_PATH tag should be used to specify the # path where java can find the plantuml.jar file or to the filename of jar file # to be used. If left blank, it is assumed PlantUML is not used or called during # a preprocessing step. Doxygen will generate a warning when it encounters a @@ -2766,20 +2893,20 @@ DIAFILE_DIRS = PLANTUML_JAR_PATH = -# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a -# configuration file for plantuml. +# When using PlantUML, the PLANTUML_CFG_FILE tag can be used to specify a +# configuration file for PlantUML. PLANTUML_CFG_FILE = -# When using plantuml, the specified paths are searched for files specified by -# the !include statement in a plantuml block. +# When using PlantUML, the specified paths are searched for files specified by +# the !include statement in a PlantUML block. PLANTUML_INCLUDE_PATH = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes -# larger than this value, doxygen will truncate the graph, which is visualized -# by representing a node as a red box. Note that doxygen if the number of direct +# larger than this value, Doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that if the number of direct # children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that # the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. @@ -2809,17 +2936,17 @@ MAX_DOT_GRAPH_DEPTH = 0 DOT_MULTI_TARGETS = NO -# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page +# If the GENERATE_LEGEND tag is set to YES Doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. -# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal +# Note: This tag requires that UML_LOOK isn't set, i.e. the Doxygen internal # graphical representation for inheritance and collaboration diagrams is used. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate +# If the DOT_CLEANUP tag is set to YES, Doxygen will remove the intermediate # files that are used to generate the various graphs. # # Note: This setting is not only used for dot files but also for msc temporary @@ -2827,3 +2954,19 @@ GENERATE_LEGEND = YES # The default value is: YES. DOT_CLEANUP = YES + +# You can define message sequence charts within Doxygen comments using the \msc +# command. If the MSCGEN_TOOL tag is left empty (the default), then Doxygen will +# use a built-in version of mscgen tool to produce the charts. Alternatively, +# the MSCGEN_TOOL tag can also specify the name an external tool. For instance, +# specifying prog as the value, Doxygen will call the tool as prog -T +# -o . The external tool should support +# output file formats "png", "eps", "svg", and "ismap". + +MSCGEN_TOOL = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = diff --git a/examples/example_dependencies.json b/examples/example_dependencies.json new file mode 100644 index 000000000..787d94b4d --- /dev/null +++ b/examples/example_dependencies.json @@ -0,0 +1,26 @@ +{ + "action_cache_version": 1, + "dependencies": [ + { + "name": "StreamDebugger", + "owner": "vshymanskyy", + "version": "~1.0.1" + }, + { + "name": "NeoSWSerial", + "version": "https://github.com/SRGDamia1/NeoSWSerial.git" + }, + { + "name": "AltSoftSerial", + "version": "https://github.com/PaulStoffregen/AltSoftSerial.git" + }, + { + "name": "SoftwareWire", + "version": "https://github.com/Testato/SoftwareWire.git#v1.5.1" + }, + { + "name": "SoftwareSerial_ExternalInts", + "version": "https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git" + } + ] +} From 5b6ab8411a422db37fea0c8f6b4e243c8e463549 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 9 Aug 2024 11:11:17 -0400 Subject: [PATCH 100/138] Use build examples workflow Signed-off-by: Sara Damiano --- .github/workflows/build_examples.yaml | 237 +------------------------- continuous_integration/platformio.ini | 12 +- src/sensors/GroPointGPLP8.h | 4 +- 3 files changed, 15 insertions(+), 238 deletions(-) diff --git a/.github/workflows/build_examples.yaml b/.github/workflows/build_examples.yaml index bfdc620ee..ec772ba06 100644 --- a/.github/workflows/build_examples.yaml +++ b/.github/workflows/build_examples.yaml @@ -8,233 +8,10 @@ concurrency: cancel-in-progress: true jobs: - generate_matrix: - name: Generate build matrices - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" - outputs: - arduino_job_matrix: ${{ steps.py_matrix.outputs.arduino_job_matrix }} - pio_job_matrix: ${{ steps.py_matrix.outputs.pio_job_matrix }} - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - cache: 'pip' - - - name: Install python dependencies, including PlatformIO - run: pip install -r continuous_integration/requirements.txt - - - name: Generate Matrices - id: py_matrix - run: | - python continuous_integration/generate_job_matrix.py - - - name: Store generated examples - uses: actions/upload-artifact@v4 - with: - name: generated_examples - path: | - continuous_integration_artifacts/ - - print_job_matrix: - name: print_job_matrix - runs-on: ubuntu-latest - needs: generate_matrix - steps: - - name: Check the generated matrix output - run: | - echo "Arduino job matrix:" - echo "${{ needs.generate_matrix.outputs.arduino_job_matrix }}" - echo - echo "PlatformIO job matrix" - echo "${{ needs.generate_matrix.outputs.pio_job_matrix }}" - - determine_library_source: - name: determine_library_source - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, 'ci skip')" - outputs: - library_install_zip: ${{ steps.store_vars.outputs.library_install_zip }} - library_install_git: ${{ steps.store_vars.outputs.library_install_git }} - - steps: - - uses: actions/checkout@v4 - - - name: Set environment variables for pushes to any branch in EnviroDIY/ModularSensors - if: github.event_name == 'push' - run: | - echo "Push to commit ${GITHUB_SHA}" - echo "LIBRARY_INSTALL_ZIP=https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.zip" >> $GITHUB_ENV - echo "LIBRARY_INSTALL_GIT=https://github.com/${GITHUB_REPOSITORY}.git#${GITHUB_SHA}" >> $GITHUB_ENV - - - name: Set environment variable for PR's from any branch in EnviroDIY/ModularSensors - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.name == github.repository - run: | - echo "Pull Request from the ${GITHUB_HEAD_REF} branch" - echo "LIBRARY_INSTALL_ZIP=https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_HEAD_REF}.zip" >> $GITHUB_ENV - echo "LIBRARY_INSTALL_GIT=https://github.com/${GITHUB_REPOSITORY}.git#${GITHUB_HEAD_REF}" >> $GITHUB_ENV - - - name: Set environment variable for PR's from any branch in EnviroDIY/ModularSensors - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.name != github.repository - run: | - echo "Pull Request from the fork ${{ github.event.pull_request.head.repo.full_name }} at ${{ github.event.pull_request.head.ref }}" - echo "LIBRARY_INSTALL_ZIP=https://github.com/${{ github.event.pull_request.head.repo.full_name }}/archive/${{ github.event.pull_request.head.ref }}.zip" >> $GITHUB_ENV - echo "LIBRARY_INSTALL_GIT=https://github.com/${{ github.event.pull_request.head.repo.full_name }}.git#${{ github.event.pull_request.head.ref }}" >> $GITHUB_ENV - - - name: store enviroment variables as output - id: store_vars - run: | - echo "library_install_zip=${{ env.LIBRARY_INSTALL_ZIP }}" >> $GITHUB_OUTPUT - echo "library_install_git=${{ env.LIBRARY_INSTALL_GIT }}" >> $GITHUB_OUTPUT - - print_library_source: - name: print_library_source - runs-on: ubuntu-latest - needs: determine_library_source - steps: - - name: Check the library installation source - run: | - echo "Link to zip for Arduino CLI testing install:" - echo "${{ needs.determine_library_source.outputs.library_install_zip }}" - echo - echo "Git reference for PlatformIO testing install" - echo "${{ needs.determine_library_source.outputs.library_install_git }}" - - build_ex_arduino: - name: ${{ matrix.job_info.job_name }} - runs-on: ubuntu-latest - needs: [generate_matrix, determine_library_source] - env: - LIBRARY_INSTALL_ZIP: ${{ needs.determine_library_source.outputs.library_install_zip }} - strategy: - matrix: - job_info: ${{ fromJSON(needs.generate_matrix.outputs.arduino_job_matrix) }} - - steps: - - uses: actions/checkout@v4 - - - name: Unused Step - run: echo "This is needed to make the step number match with the PlatformIO jobs. =)" - - # We use the `arduino/setup-arduino-cli` action to install and - # configure the Arduino CLI on the system. - - name: Setup Arduino CLI - uses: arduino/setup-arduino-cli@v1.1.2 - - - name: Restore Arduino platforms and libraries - uses: actions/cache@v4 - id: cache_libraries - with: - path: | - home/arduino - # if nothing in the dependencies.json file has changed, then it will - # be a "cache hit" and we can restore libraries from cache and not - # download them. If it has changed we have to re-download. - key: ${{ hashFiles('./continuous_integration/dependencies.json','continuous_integration/install-deps-arduino-cli.sh') }} - - # Install cores and library dependencies for the Arduino CLI, iff no cache - - name: Install the Arduino libraries - if: steps.cache_libraries.outputs.cache-hit != 'true' - run: | - chmod +x continuous_integration/install-deps-arduino-cli.sh - sh continuous_integration/install-deps-arduino-cli.sh - - # Install ModularSensors for the Arduino CLI - - name: Install the testing version of Modular Sensors for the Arduino CLI - run: | - chmod +x continuous_integration/install-test-version-arduino-cli.sh - sh continuous_integration/install-test-version-arduino-cli.sh - - - name: Download the prepared examples - uses: actions/download-artifact@v4 - with: - name: generated_examples - path: | - continuous_integration_artifacts/ - - - name: Include problem matcher - uses: ammaraskar/gcc-problem-matcher@master - - # Run the script to compile the examples - - name: Compile - env: - ACTION_RUN_ID: ${{ github.run_id }} - run: | - chmod +x ${{ matrix.job_info.script }} - bash ${{ matrix.job_info.script }} - - # NOTE: Don't uninstall for PlatformIO because the library manager will clean up the - # dependencies leaving nothing for the cache - # pio pkg uninstall --library -g EnviroDIY_ModularSensors - - name: Uninstall testing version of Modular Sensors before caching - run: | - arduino-cli --config-file continuous_integration/arduino_cli.yaml lib uninstall ModularSensors - - build_pio: - name: ${{ matrix.job_info.job_name }} - runs-on: ubuntu-latest - needs: [generate_matrix, determine_library_source] - env: - LIBRARY_INSTALL_GIT: ${{ needs.determine_library_source.outputs.library_install_git }} - strategy: - matrix: - job_info: ${{ fromJSON(needs.generate_matrix.outputs.pio_job_matrix) }} - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - cache: 'pip' - - - name: Install python dependencies, including PlatformIO - run: pip install -r continuous_integration/requirements.txt - - - name: Restore PlatformIO platforms and libraries - uses: actions/cache@v4 - id: cache_libraries - with: - path: | - ~/.platformio - # if nothing in the dependencies.json file has changed, then it will - # be a "cache hit" and we can restore libraries from cache and not - # download them. If it has changed we have to re-download. - key: ${{ hashFiles('./continuous_integration/dependencies.json','continuous_integration/install-deps-platformio.sh') }} - - # Install the dependencies for PlatformIO - - name: Install the PlatformIO dependencies at global level - if: steps.cache_libraries.outputs.cache-hit != 'true' - run: | - chmod +x continuous_integration/install-deps-platformio.sh - sh continuous_integration/install-deps-platformio.sh - cp -a /home/runner/.platformio/lib/. $GITHUB_WORKSPACE/lib/ - - # Install ModularSensors at the Global level for PlatformIO - # Force install to get the right version - - name: Install the testing version of Modular Sensors for PlatformIO - run: | - pio pkg install -g --library ${{ env.LIBRARY_INSTALL_GIT }} - - - name: Download the prepared examples - uses: actions/download-artifact@v4 - with: - name: generated_examples - path: | - continuous_integration_artifacts/ - - - name: Include problem matcher - uses: ammaraskar/gcc-problem-matcher@master - - # Run the script to compile the examples - - name: Compile - env: - ACTION_RUN_ID: ${{ github.run_id }} - run: | - chmod +x ${{ matrix.job_info.script }} - bash ${{ matrix.job_info.script }} + build_examples: + name: Build all examples with PlatformIO and the Arduino CLI + if: ${{ ! contains(github.event.head_commit.message, 'ci skip') }} + uses: EnviroDIY/workflows/.github/workflows/build_examples.yaml@main + with: + boards_to_build: 'mayfly,megaatmega2560,zeroUSB,adafruit_feather_m0' + secrets: inherit diff --git a/continuous_integration/platformio.ini b/continuous_integration/platformio.ini index 263173d30..6b56d0d53 100644 --- a/continuous_integration/platformio.ini +++ b/continuous_integration/platformio.ini @@ -26,7 +26,7 @@ build_flags = -D SDI12_EXTERNAL_PCINT -D NEOSWSERIAL_EXTERNAL_PCINT -[env:Mayfly] +[env:mayfly] board = mayfly platform = atmelavr lib_ignore = @@ -36,7 +36,7 @@ lib_ignore = build_flags = ${env.build_flags} -[env:Mega] +[env:mega] platform = atmelavr board = megaatmega2560 lib_ignore = @@ -46,7 +46,7 @@ lib_ignore = build_flags = ${env.build_flags} -[env:Zero] +[env:zero] platform = atmelsam board = zeroUSB lib_ignore = @@ -58,7 +58,7 @@ lib_ignore = build_flags = ${env.build_flags} -[env:FeatherM0] +[env:feather_m0] platform = atmelsam board = adafruit_feather_m0 lib_ignore = @@ -71,7 +71,7 @@ build_flags = ${env.build_flags} build_unflags = -D USE_TINYUSB -; [env:FeatherM4] +; [env:feather_m4] ; platform = atmelsam ; board = adafruit_feather_m4 ; lib_ignore = @@ -86,7 +86,7 @@ build_unflags = -D USE_TINYUSB ; -D MS_SAMD_DS3231 ; build_unflags = -D USE_TINYUSB -; [env:GrandCentralM4] +; [env:grandcentral_m4] ; platform = atmelsam ; board = adafruit_grandcentral_m4 ; lib_ignore = diff --git a/src/sensors/GroPointGPLP8.h b/src/sensors/GroPointGPLP8.h index 869ea74b3..c73a34244 100644 --- a/src/sensors/GroPointGPLP8.h +++ b/src/sensors/GroPointGPLP8.h @@ -26,7 +26,7 @@ * Profiling Probe. Classes for the GroPoint Profile GPLP-8 Soil Moisture & * Temperature Probe. * - * @ingroup GroPoint_group + * @ingroup gropoint_group * * @tableofcontents * @m_footernavigation @@ -34,7 +34,7 @@ * @section sensor_gplp8_datasheet Sensor Datasheet * - [GroPoint Profile User Manual](https://www.gropoint.com/s/2625-N-T-GroPoint-Profile-User-Manual-V113.pdf), including Modbus Instructions. * - [GroPoint Profile Technical Info](https://www.gropoint.com/s/GroPoint-Profile-Technical-Info.pdf) - * * + * * @section sensor_gplp8_ctor Sensor Constructor * {{ @ref GroPointGPLP8::GroPointGPLP8 }} * From f09491d32505610a340ead79558056d6682cebe7 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 15 Aug 2024 12:53:35 -0400 Subject: [PATCH 101/138] Update doxyfile Signed-off-by: Sara Damiano --- docs/Doxyfile | 57 +- .../m-EnviroDIY+documentation.compiled.css | 4397 ----------------- docs/markdown_prefilter.py | 355 -- 3 files changed, 30 insertions(+), 4779 deletions(-) delete mode 100644 docs/css/m-EnviroDIY+documentation.compiled.css delete mode 100644 docs/markdown_prefilter.py diff --git a/docs/Doxyfile b/docs/Doxyfile index f6ceb512d..3b2217a8f 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -67,7 +67,7 @@ PROJECT_LOGO = ModularSensors_ubuntu_264x55.png # when the HTML document is shown. Doxygen will copy the logo to the output # directory. -PROJECT_ICON = +PROJECT_ICON = enviroDIY_Favicon.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is @@ -135,7 +135,7 @@ BRIEF_MEMBER_DESC = YES # brief descriptions will be completely suppressed. # The default value is: YES. -REPEAT_BRIEF = YES +REPEAT_BRIEF = NO # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found @@ -245,7 +245,7 @@ QT_AUTOBRIEF = NO # not recognized any more. # The default value is: NO. -MULTILINE_CPP_IS_BRIEF = NO +MULTILINE_CPP_IS_BRIEF = YES # By default Python docstrings are displayed as preformatted text and Doxygen's # special commands cannot be used. By setting PYTHON_DOCSTRING to NO the @@ -289,9 +289,9 @@ TAB_SIZE = 4 # with the commands \{ and \} for these it is advised to use the version @{ and # @} or use a double escape (\\{ and \\}) -ALIASES = "license=@par License:\n" \ - "environment=@par Development Environment:\n" \ - "platform=@par Hardware Platform:\n" \ +ALIASES = "license=@par License^^" \ + "environment=@par Development Environment^^" \ + "platform=@par Hardware Platform^^" \ "m_div{1}=@xmlonly@endxmlonly" \ "m_enddiv=@xmlonly@endxmlonly" \ "m_span{1}=@xmlonly@endxmlonly" \ @@ -541,19 +541,19 @@ TIMESTAMP = YES # normally produced when WARNINGS is set to YES. # The default value is: NO. -EXTRACT_ALL = YES +EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. -EXTRACT_PRIVATE = NO +EXTRACT_PRIVATE = YES # If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual # methods of a class will be included in the documentation. # The default value is: NO. -EXTRACT_PRIV_VIRTUAL = NO +EXTRACT_PRIV_VIRTUAL = YES # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. @@ -565,7 +565,7 @@ EXTRACT_PACKAGE = NO # included in the documentation. # The default value is: NO. -EXTRACT_STATIC = NO +EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, @@ -940,7 +940,7 @@ WARN_IF_UNDOC_ENUM_VAL = YES # Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. # The default value is: NO. -WARN_AS_ERROR = FAIL_ON_WARNINGS +WARN_AS_ERROR = FAIL_ON_WARNINGS_PRINT # The WARN_FORMAT tag determines the format of the warning messages that Doxygen # can produce. The string should contain the $file, $line, and $text tags, which @@ -1032,6 +1032,7 @@ FILE_PATTERNS = *.c \ *.hxx \ *.hpp \ *.h++ \ + *.tpp \ *.inc \ *.m \ *.markdown \ @@ -1039,8 +1040,7 @@ FILE_PATTERNS = *.c \ *.mm \ *.dox \ *.doc \ - *.txt \ - *.tpp + *.txt # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. @@ -1059,7 +1059,10 @@ EXCLUDE = ../src/ReadMe.md \ ../examples/logger_test \ ../examples/logger_test_nonew \ ../examples/YosemitechDO \ - ../src/sensors/table.md + ../src/sensors/table.md \ + ../lib \ + ../boards \ + ../variants # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -1177,7 +1180,7 @@ FILTER_SOURCE_PATTERNS = # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the Doxygen output. -USE_MDFILE_AS_MAINPAGE = README.md +USE_MDFILE_AS_MAINPAGE = # The Fortran standard specifies that for fixed formatted Fortran code all # characters from position 72 are to be considered as comment. A common @@ -2620,7 +2623,7 @@ HIDE_UNDOC_RELATIONS = NO # set to NO # The default value is: NO. -HAVE_DOT = YES +HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations Doxygen is allowed # to run in parallel. When set to 0 Doxygen will base this on the number of @@ -2683,7 +2686,7 @@ DOT_FONTPATH = # Possible values are: NO, YES, TEXT, GRAPH and BUILTIN. # The default value is: YES. -CLASS_GRAPH = YES +CLASS_GRAPH = NO # If the COLLABORATION_GRAPH tag is set to YES then Doxygen will generate a # graph for each documented class showing the direct and indirect implementation @@ -2695,7 +2698,7 @@ CLASS_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -COLLABORATION_GRAPH = YES +COLLABORATION_GRAPH = NO # If the GROUP_GRAPHS tag is set to YES then Doxygen will generate a graph for # groups, showing the direct groups dependencies. Explicit enabling a group @@ -2706,7 +2709,7 @@ COLLABORATION_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -GROUP_GRAPHS = YES +GROUP_GRAPHS = NO # If the UML_LOOK tag is set to YES, Doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling @@ -2757,7 +2760,7 @@ DOT_WRAP_THRESHOLD = 17 # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -TEMPLATE_RELATIONS = YES +TEMPLATE_RELATIONS = NO # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to # YES then Doxygen will generate a graph for each documented file showing the @@ -2768,7 +2771,7 @@ TEMPLATE_RELATIONS = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDE_GRAPH = YES +INCLUDE_GRAPH = NO # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then Doxygen will generate a graph for each documented file showing @@ -2780,7 +2783,7 @@ INCLUDE_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDED_BY_GRAPH = YES +INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH tag is set to YES then Doxygen will generate a call # dependency graph for every global function or class method. @@ -2792,7 +2795,7 @@ INCLUDED_BY_GRAPH = YES # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -CALL_GRAPH = YES +CALL_GRAPH = NO # If the CALLER_GRAPH tag is set to YES then Doxygen will generate a caller # dependency graph for every global function or class method. @@ -2804,14 +2807,14 @@ CALL_GRAPH = YES # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -CALLER_GRAPH = YES +CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY tag is set to YES then Doxygen will graphical # hierarchy of all classes instead of a textual one. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -GRAPHICAL_HIERARCHY = YES +GRAPHICAL_HIERARCHY = NO # If the DIRECTORY_GRAPH tag is set to YES then Doxygen will show the # dependencies a directory has on other directories in a graphical way. The @@ -2823,7 +2826,7 @@ GRAPHICAL_HIERARCHY = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -DIRECTORY_GRAPH = YES +DIRECTORY_GRAPH = NO # The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels # of child directories generated in directory dependency graphs by dot. @@ -2845,7 +2848,7 @@ DIR_GRAPH_MAX_DEPTH = 5 # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_IMAGE_FORMAT = png +DOT_IMAGE_FORMAT = svg # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. diff --git a/docs/css/m-EnviroDIY+documentation.compiled.css b/docs/css/m-EnviroDIY+documentation.compiled.css deleted file mode 100644 index ce5c1158e..000000000 --- a/docs/css/m-EnviroDIY+documentation.compiled.css +++ /dev/null @@ -1,4397 +0,0 @@ -/* Generated using `./postprocess.py m-EnviroDIY.css m-documentation.css -o m-EnviroDIY+documentation.compiled.css`. Do not edit. */ - -/* - This file is part of m.css. - - Copyright © 2017, 2018, 2019, 2020, 2021, 2022 - Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -*, ::before, ::after { box-sizing: border-box; } -body { margin: 0; } -.m-container { - width: 100%; - margin: auto; - padding-left: 1rem; - padding-right: 1rem; -} -.m-row { - margin-left: -1rem; - margin-right: -1rem; -} -.m-row::after { - content: ' '; - clear: both; - display: table; -} -.m-row > [class*='m-col-'] { - position: relative; - padding: 1rem; -} -[class*='m-clearfix-']::after { - display: block; - content: ' '; - clear: both; -} -[class*='m-show-'] { - display: none; -} -.m-container-inflate, :not(.m-row) > [class*='m-col-'] { - margin-bottom: 1rem; -} -.m-container-inflate:last-child, :not(.m-row) > [class*='m-col-']:last-child { - margin-bottom: 0; -} -.m-container.m-nopad, [class*='m-col-'].m-nopad, -.m-container.m-nopadx, [class*='m-col-'].m-nopadx, -.m-container.m-nopadl, [class*='m-col-'].m-nopadl { - padding-left: 0; -} -.m-container.m-nopad, [class*='m-col-'].m-nopad, -.m-container.m-nopadx, [class*='m-col-'].m-nopadx, -.m-container.m-nopadr, [class*='m-col-'].m-nopadr { - padding-right: 0; -} -[class*='m-col-'].m-nopad, [class*='m-col-'].m-nopady, [class*='m-col-'].m-nopadt { - padding-top: 0; -} -[class*='m-col-'].m-nopad, [class*='m-col-'].m-nopady, [class*='m-col-'].m-nopadb, -.m-container-inflate.m-nopadb { - padding-bottom: 0; -} -[class*='m-col-t-'] { float: left; } -.m-left-t { - padding-right: 1rem; - float: left; -} -.m-right-t, [class*='m-col-t-'].m-right-t { - padding-left: 1rem; - float: right; -} -.m-center-t, [class*='m-col-t-'].m-center-t { - float: none; -} -.m-center-t, [class*='m-col-t-'].m-center-t { - margin-left: auto; - margin-right: auto; - float: none; -} -.m-col-t-1 { width: calc(1 * 100% / 12); } -.m-col-t-2 { width: calc(2 * 100% / 12); } -.m-col-t-3 { width: calc(3 * 100% / 12); } -.m-col-t-4 { width: calc(4 * 100% / 12); } -.m-col-t-5 { width: calc(5 * 100% / 12); } -.m-col-t-6 { width: calc(6 * 100% / 12); } -.m-col-t-7 { width: calc(7 * 100% / 12); } -.m-col-t-8 { width: calc(8 * 100% / 12); } -.m-col-t-9 { width: calc(9 * 100% / 12); } -.m-col-t-10 { width: calc(10 * 100% / 12); } -.m-col-t-11 { width: calc(11 * 100% / 12); } -.m-col-t-12 { width: calc(12 * 100% / 12); } -.m-push-t-1 { left: calc(1 * 100% / 12); } -.m-push-t-2 { left: calc(2 * 100% / 12); } -.m-push-t-3 { left: calc(3 * 100% / 12); } -.m-push-t-4 { left: calc(4 * 100% / 12); } -.m-push-t-5 { left: calc(5 * 100% / 12); } -.m-push-t-6 { left: calc(6 * 100% / 12); } -.m-push-t-7 { left: calc(7 * 100% / 12); } -.m-push-t-8 { left: calc(8 * 100% / 12); } -.m-push-t-9 { left: calc(9 * 100% / 12); } -.m-push-t-10 { left: calc(10 * 100% / 12); } -.m-push-t-11 { left: calc(11 * 100% / 12); } -.m-pull-t-1 { right: calc(1 * 100% / 12); } -.m-pull-t-2 { right: calc(2 * 100% / 12); } -.m-pull-t-3 { right: calc(3 * 100% / 12); } -.m-pull-t-4 { right: calc(4 * 100% / 12); } -.m-pull-t-5 { right: calc(5 * 100% / 12); } -.m-pull-t-6 { right: calc(6 * 100% / 12); } -.m-pull-t-7 { right: calc(7 * 100% / 12); } -.m-pull-t-8 { right: calc(8 * 100% / 12); } -.m-pull-t-9 { right: calc(9 * 100% / 12); } -.m-pull-t-10 { right: calc(10 * 100% / 12); } -.m-pull-t-11 { right: calc(11 * 100% / 12); } -@media screen and (min-width: 576px) { - .m-container { width: 560px; } - .m-container-inflatable .m-col-s-10 .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { - margin-left: -10%; - margin-right: -10%; - } - .m-container-inflatable .m-col-s-10 .m-container-inflate.m-left-s { - margin-left: -10%; - } - .m-container-inflatable .m-col-s-10 .m-container-inflate.m-right-s { - margin-right: -10%; - } - [class*='m-col-s-'] { float: left; } - .m-left-s { - padding-right: 1rem; - float: left; - } - .m-right-s, [class*='m-col-s-'].m-right-s { - padding-left: 1rem; - float: right; - } - .m-center-s, [class*='m-col-s-'].m-center-s { - margin-left: auto; - margin-right: auto; - float: none; - } - .m-col-s-1 { width: calc(1 * 100% / 12); } - .m-col-s-2 { width: calc(2 * 100% / 12); } - .m-col-s-3 { width: calc(3 * 100% / 12); } - .m-col-s-4 { width: calc(4 * 100% / 12); } - .m-col-s-5 { width: calc(5 * 100% / 12); } - .m-col-s-6 { width: calc(6 * 100% / 12); } - .m-col-s-7 { width: calc(7 * 100% / 12); } - .m-col-s-8 { width: calc(8 * 100% / 12); } - .m-col-s-9 { width: calc(9 * 100% / 12); } - .m-col-s-10 { width: calc(10 * 100% / 12); } - .m-col-s-11 { width: calc(11 * 100% / 12); } - .m-col-s-12 { width: calc(12 * 100% / 12); } - .m-push-s-0 { left: calc(0 * 100% / 12); } - .m-push-s-1 { left: calc(1 * 100% / 12); } - .m-push-s-2 { left: calc(2 * 100% / 12); } - .m-push-s-3 { left: calc(3 * 100% / 12); } - .m-push-s-4 { left: calc(4 * 100% / 12); } - .m-push-s-5 { left: calc(5 * 100% / 12); } - .m-push-s-6 { left: calc(6 * 100% / 12); } - .m-push-s-7 { left: calc(7 * 100% / 12); } - .m-push-s-8 { left: calc(8 * 100% / 12); } - .m-push-s-9 { left: calc(9 * 100% / 12); } - .m-push-s-10 { left: calc(10 * 100% / 12); } - .m-push-s-11 { left: calc(11 * 100% / 12); } - .m-pull-s-0 { right: calc(0 * 100% / 12); } - .m-pull-s-1 { right: calc(1 * 100% / 12); } - .m-pull-s-2 { right: calc(2 * 100% / 12); } - .m-pull-s-3 { right: calc(3 * 100% / 12); } - .m-pull-s-4 { right: calc(4 * 100% / 12); } - .m-pull-s-5 { right: calc(5 * 100% / 12); } - .m-pull-s-6 { right: calc(6 * 100% / 12); } - .m-pull-s-7 { right: calc(7 * 100% / 12); } - .m-pull-s-8 { right: calc(8 * 100% / 12); } - .m-pull-s-9 { right: calc(9 * 100% / 12); } - .m-pull-s-10 { right: calc(10 * 100% / 12); } - .m-pull-s-11 { right: calc(11 * 100% / 12); } - .m-clearfix-t::after { display: none; } - .m-hide-s { display: none; } - .m-show-s { display: block; } - .m-col-s-none { - width: auto; - float: none; - } -} -@media screen and (min-width: 768px) { - .m-container { width: 750px; } - .m-container-inflatable .m-col-m-10 .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { - margin-left: -10%; - margin-right: -10%; - } - .m-container-inflatable .m-col-m-10 .m-container-inflate.m-left-m { - margin-left: -10%; - } - .m-container-inflatable .m-col-m-10 .m-container-inflate.m-right-m { - margin-right: -10%; - } - [class*='m-col-m-'] { float: left; } - .m-left-m { - padding-right: 1rem; - float: left; - } - .m-right-m, [class*='m-col-m-'].m-right-m { - padding-left: 1rem; - float: right; - } - .m-center-m, [class*='m-col-m-'].m-center-m { - margin-left: auto; - margin-right: auto; - float: none; - } - .m-col-m-1 { width: calc(1 * 100% / 12); } - .m-col-m-2 { width: calc(2 * 100% / 12); } - .m-col-m-3 { width: calc(3 * 100% / 12); } - .m-col-m-4 { width: calc(4 * 100% / 12); } - .m-col-m-5 { width: calc(5 * 100% / 12); } - .m-col-m-6 { width: calc(6 * 100% / 12); } - .m-col-m-7 { width: calc(7 * 100% / 12); } - .m-col-m-8 { width: calc(8 * 100% / 12); } - .m-col-m-9 { width: calc(9 * 100% / 12); } - .m-col-m-10 { width: calc(10 * 100% / 12); } - .m-col-m-11 { width: calc(11 * 100% / 12); } - .m-col-m-12 { width: calc(12 * 100% / 12); } - .m-push-m-0 { left: calc(0 * 100% / 12); } - .m-push-m-1 { left: calc(1 * 100% / 12); } - .m-push-m-2 { left: calc(2 * 100% / 12); } - .m-push-m-3 { left: calc(3 * 100% / 12); } - .m-push-m-4 { left: calc(4 * 100% / 12); } - .m-push-m-5 { left: calc(5 * 100% / 12); } - .m-push-m-6 { left: calc(6 * 100% / 12); } - .m-push-m-7 { left: calc(7 * 100% / 12); } - .m-push-m-8 { left: calc(8 * 100% / 12); } - .m-push-m-9 { left: calc(9 * 100% / 12); } - .m-push-m-10 { left: calc(10 * 100% / 12); } - .m-push-m-11 { left: calc(11 * 100% / 12); } - .m-pull-m-0 { right: calc(0 * 100% / 12); } - .m-pull-m-1 { right: calc(1 * 100% / 12); } - .m-pull-m-2 { right: calc(2 * 100% / 12); } - .m-pull-m-3 { right: calc(3 * 100% / 12); } - .m-pull-m-4 { right: calc(4 * 100% / 12); } - .m-pull-m-5 { right: calc(5 * 100% / 12); } - .m-pull-m-6 { right: calc(6 * 100% / 12); } - .m-pull-m-7 { right: calc(7 * 100% / 12); } - .m-pull-m-8 { right: calc(8 * 100% / 12); } - .m-pull-m-9 { right: calc(9 * 100% / 12); } - .m-pull-m-10 { right: calc(10 * 100% / 12); } - .m-pull-m-11 { right: calc(11 * 100% / 12); } - .m-clearfix-s::after { display: none; } - .m-hide-m { display: none; } - .m-show-m { display: block; } - .m-col-m-none { - width: auto; - float: none; - } -} -@media screen and (min-width: 992px) { - .m-container { width: 960px; } - .m-container-inflatable .m-col-l-10 .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { - margin-left: -10%; - margin-right: -10%; - } - .m-container-inflatable .m-col-l-10 .m-container-inflate.m-left-l { - margin-left: -10%; - } - .m-container-inflatable .m-col-l-10 .m-container-inflate.m-right-l { - margin-right: -10%; - } - [class*='m-col-l-'] { float: left; } - .m-left-l { - padding-right: 1rem; - float: left; - } - .m-right-l, [class*='m-col-l-'].m-right-l { - padding-left: 1rem; - float: right; - } - .m-center-l, [class*='m-col-l-'].m-center-l { - margin-left: auto; - margin-right: auto; - float: none; - } - .m-col-l-1 { width: calc(1 * 100% / 12); } - .m-col-l-2 { width: calc(2 * 100% / 12); } - .m-col-l-3 { width: calc(3 * 100% / 12); } - .m-col-l-4 { width: calc(4 * 100% / 12); } - .m-col-l-5 { width: calc(5 * 100% / 12); } - .m-col-l-6 { width: calc(6 * 100% / 12); } - .m-col-l-7 { width: calc(7 * 100% / 12); } - .m-col-l-8 { width: calc(8 * 100% / 12); } - .m-col-l-9 { width: calc(9 * 100% / 12); } - .m-col-l-10 { width: calc(10 * 100% / 12); } - .m-col-l-11 { width: calc(11 * 100% / 12); } - .m-col-l-12 { width: calc(12 * 100% / 12); } - .m-push-l-0 { left: calc(0 * 100% / 12); } - .m-push-l-1 { left: calc(1 * 100% / 12); } - .m-push-l-2 { left: calc(2 * 100% / 12); } - .m-push-l-3 { left: calc(3 * 100% / 12); } - .m-push-l-4 { left: calc(4 * 100% / 12); } - .m-push-l-5 { left: calc(5 * 100% / 12); } - .m-push-l-6 { left: calc(6 * 100% / 12); } - .m-push-l-7 { left: calc(7 * 100% / 12); } - .m-push-l-8 { left: calc(8 * 100% / 12); } - .m-push-l-9 { left: calc(9 * 100% / 12); } - .m-push-l-10 { left: calc(10 * 100% / 12); } - .m-push-l-11 { left: calc(11 * 100% / 12); } - .m-pull-l-0 { right: calc(0 * 100% / 12); } - .m-pull-l-1 { right: calc(1 * 100% / 12); } - .m-pull-l-2 { right: calc(2 * 100% / 12); } - .m-pull-l-3 { right: calc(3 * 100% / 12); } - .m-pull-l-4 { right: calc(4 * 100% / 12); } - .m-pull-l-5 { right: calc(5 * 100% / 12); } - .m-pull-l-6 { right: calc(6 * 100% / 12); } - .m-pull-l-7 { right: calc(7 * 100% / 12); } - .m-pull-l-8 { right: calc(8 * 100% / 12); } - .m-pull-l-9 { right: calc(9 * 100% / 12); } - .m-pull-l-10 { right: calc(10 * 100% / 12); } - .m-pull-l-11 { right: calc(11 * 100% / 12); } - .m-clearfix-m::after { display: none; } - .m-hide-l { display: none; } - .m-show-l { display: block; } - .m-col-l-none { - width: auto; - float: none; - } -} - -html { - font-size: 14px; - background-color: #e8e8e8; -} -body { - font-family: 'Roboto', sans-serif; - font-size: 14px; - line-height: normal; - color: #000000; -} -h1, -h2, -h3, -h4, -h5, -h6 { - margin-top: 0; - font-weight: 300; -} -h1 { - margin-bottom: 1rem; -} -h2, -h3, -h4, -h5, -h6 { - margin-bottom: 0.5rem; -} -p, -ul, -ol, -dl { - margin-top: 0; -} -ul, -ol { - padding-left: 2rem; -} -ul ol, -ul ul, -ol ol, -ol ul { - margin-bottom: 0; -} -main p { - text-indent: 1.5rem; - text-align: justify; -} -main p.m-noindent, -li > p, -dd > p, -table.m-table td > p { - text-indent: 0; - text-align: left; -} -blockquote { - margin-top: 0; - margin-left: 1rem; - margin-right: 1rem; - padding: 1rem; - border-left-style: solid; - border-left-width: 0.25rem; -} -hr { - width: 75%; - border-width: 0.0625rem; - border-style: solid; -} -blockquote, -hr { - border-color: #92d050; -} -strong, -.m-text.m-strong { - font-weight: bold; -} -em, -.m-text.m-em { - font-style: italic; -} -s, -.m-text.m-s { - text-decoration: line-through; -} -sub, -sup, -.m-text.m-sub, -.m-text.m-sup { - font-size: 0.75rem; - line-height: 0; - position: relative; - vertical-align: baseline; -} -sup, -.m-text.m-sup { - top: -0.35rem; -} -sub, -.m-text.m-sub { - bottom: -0.2rem; -} -abbr { - cursor: help; - text-decoration: underline dotted; -} -a { - color: #26a9e0; -} -a.m-flat { - text-decoration: none; -} -a:hover, -a:focus, -a:active { - color: #26a9e0; -} -a img { - border: 0; -} -svg a { - cursor: pointer; -} -mark { - padding: 0.0625rem; - background-color: #e6e69c; - color: #4c93d3; -} -.m-link-wrap { - word-break: break-all; -} -pre, -code { - font-family: 'Monaco', monospace, monospace, monospace; - font-size: 0.95em; - color: #000000; - background-color: #f7f7f7; -} -pre.m-console, -code.m-console { - color: #000000; - background-color: #f7f7f7; -} -pre { - padding: 0.5rem 1rem; - border-radius: 0px; - overflow-x: auto; - margin-top: 0; -} -pre.m-console-wrap { - white-space: pre-wrap; - word-break: break-all; -} -code { - padding: 0.125rem; -} -*:focus { - outline-color: #ffffff; -} -div.m-scroll { - max-width: 100%; - overflow-x: auto; -} -.m-fullwidth { - width: 100%; -} -.m-spacing-150 { - line-height: 1.5rem; -} -.m-text-center, -.m-text-center.m-noindent, -table.m-table th.m-text-center, -.m-text-center p { - text-align: center; -} -.m-text-left, -.m-text-left.m-noindent, -table.m-table th.m-text-left, -.m-text-right p { - text-align: left; -} -.m-text-right, -.m-text-right.m-noindent, -table.m-table th.m-text-right, -.m-text-right p { - text-align: right; -} -.m-text-top, -table.m-table th.m-text-top, -table.m-table td.m-text-top { - vertical-align: top; -} -.m-text-middle, -table.m-table th.m-text-middle, -table.m-table td.m-text-middle { - vertical-align: middle; -} -.m-text-bottom, -table.m-table th.m-text-bottom, -table.m-table td.m-text-bottom { - vertical-align: bottom; -} -.m-text.m-tiny { - font-size: 50%; -} -.m-text.m-small { - font-size: 85.4%; -} -.m-text.m-big { - font-size: 117%; -} -h1 .m-thin, -h2 .m-thin, -h3 .m-thin, -h4 .m-thin, -h5 .m-thin, -h6 .m-thin { - font-weight: normal; - font-size: 75%; - color: #666; -} -ul.m-unstyled, -ol.m-unstyled { - list-style-type: none; - padding-left: 0; -} -ul[class*="m-block-"], -ol[class*="m-block-"] { - padding-left: 0; -} -ul[class*="m-block-"] li, -ol[class*="m-block-"] li { - display: inline; -} -ul[class*="m-block-bar-"] li:not(:last-child)::after, -ol[class*="m-block-bar-"] li:not(:last-child)::after { - content: " | "; -} -ul[class*="m-block-dot-"] li:not(:last-child)::after, -ol[class*="m-block-dot-"] li:not(:last-child)::after { - content: " • "; -} -@media screen and (min-width: 576px) { - ul.m-block-bar-s, - ol.m-block-bar-s, - ul.m-block-dot-s, - ol.m-block-dot-s { - padding-left: 2rem; - } - ul.m-block-bar-s li, - ol.m-block-bar-s li, - ul.m-block-dot-s li, - ol.m-block-dot-s li { - display: list-item; - } - ul.m-block-bar-s li:not(:last-child)::after, - ol.m-block-bar-s li:not(:last-child)::after, - ul.m-block-dot-s li:not(:last-child)::after, - ol.m-block-dot-s li:not(:last-child)::after { - content: ""; - } -} -@media screen and (min-width: 768px) { - ul.m-block-bar-m, - ol.m-block-bar-m, - ul.m-block-dot-m, - ol.m-block-dot-m { - padding-left: 2rem; - } - ul.m-block-bar-m li, - ol.m-block-bar-m li, - ul.m-block-dot-m li, - ol.m-block-dot-m li { - display: list-item; - } - ul.m-block-bar-m li:not(:last-child)::after, - ol.m-block-bar-m li:not(:last-child)::after, - ul.m-block-dot-m li:not(:last-child)::after, - ol.m-block-dot-m li:not(:last-child)::after { - content: ""; - } -} -@media screen and (min-width: 992px) { - ul.m-block-bar-l, - ol.m-block-bar-l, - ul.m-block-dot-l, - ol.m-block-dot-l { - padding-left: 2rem; - } - ul.m-block-bar-l li, - ol.m-block-bar-l li, - ul.m-block-dot-l li, - ol.m-block-dot-l li { - display: list-item; - } - ul.m-block-bar-l li:not(:last-child)::after, - ol.m-block-bar-l li:not(:last-child)::after, - ul.m-block-dot-l li:not(:last-child)::after, - ol.m-block-dot-l li:not(:last-child)::after { - content: ""; - } -} -p.m-poem { - text-indent: 0; - text-align: left; - margin-left: 1.5rem; -} -p.m-transition { - color: #ddd; - text-indent: 0; - text-align: center; - font-size: 2rem; -} -dl.m-diary { - margin-bottom: 1.25rem; -} -dl.m-diary:last-child { - margin-bottom: 0.25rem; -} -dl.m-diary dt { - font-weight: bold; - width: 6rem; - float: left; - clear: both; - padding-top: 0.25rem; -} -dl.m-diary dd { - padding-top: 0.25rem; - padding-left: 6rem; - margin-left: 0; -} -a.m-footnote, -dl.m-footnote dd span.m-footnote { - top: -0.35rem; - font-size: 0.75rem; - line-height: 0; - position: relative; - vertical-align: baseline; -} -a.m-footnote, -dl.m-footnote dd span.m-footnote a { - text-decoration: none; -} -a.m-footnote::before { - content: "["; -} -a.m-footnote::after { - content: "]"; -} -dl.m-footnote dt { - width: 1.5rem; - float: left; - clear: both; -} -dl.m-footnote dd { - margin-left: 1.5rem; -} -dl.m-footnote { - font-size: 85.4%; -} -dl.m-footnote dd span.m-footnote a { - font-weight: bold; - font-style: italic; -} -.m-container-inflatable { - background-color: #ffffff; -} -.m-note { - border-radius: 0px; - padding: 1rem; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-frame { - background-color: #e8e8e8; - border-style: solid; - border-width: 0.125rem; - border-radius: 0px; - border-color: #ddd; - padding: 0.875rem; -} -.m-block { - border-style: solid; - border-width: 0.0625rem; - border-radius: 0px; - border-color: #ddd; - padding: 0.9375rem 0.9375rem 0.9375rem 0.75rem; -} -.m-block.hr { - width: 75%; - border-width: 0.0625rem; - border-style: solid; - border-color: #92d050; -} -.m-block.m-row.hr { - width: 75%; - border-width: 0.0625rem; - border-style: solid; - border-color: #92d050; -} -.m-block.m-badge::after { - content: " "; - display: block; - clear: both; -} -.m-block.m-badge h3 { - margin-left: 5rem; -} -.m-block.m-badge p { - margin-left: 5rem; - text-indent: 0; -} -.m-block.m-badge img { - width: 4rem; - height: 4rem; - border-radius: 0.5rem; - float: left; -} -div.m-button { - text-align: center; -} -div.m-button a { - display: inline-block; - border-radius: 0.5rem; - padding-top: 0.75rem; - padding-bottom: 0.75rem; - padding-left: 1.5rem; - padding-right: 1.5rem; - text-decoration: none; - font-size: 1.17rem; -} -div.m-button.m-fullwidth a { - display: block; - padding-left: 0.5rem; - padding-right: 0.5rem; -} -div.m-button a .m-big:first-child { - font-size: 1.37rem; - font-weight: bold; -} -div.m-button a .m-small:last-child { - font-size: 0.854rem; -} -.m-label { - border-radius: 0.5rem; - font-size: 75%; - font-weight: normal; - padding: 0.125rem 0.25rem; - vertical-align: 7.5%; -} -.m-label.m-flat { - border-width: 0.0625rem; - border-style: solid; - border-color: #666; - padding: 0.0625rem 0.1875rem; -} -table.m-table { - border-collapse: collapse; - margin-left: auto; - margin-right: auto; - font-size: 0.9em; -} -table.m-table.m-big { - margin-top: 1.75rem; -} -div.m-scroll > table.m-table:last-child { - margin-bottom: 0.0625rem; -} -table.m-table:not(.m-flat) tbody tr:hover { - background-color: #ddd; -} -table.m-table tr, -table.m-table th, -table.m-table td { - vertical-align: top; - border-style: solid; - border-top-width: 0.0625rem; - border-left-width: 0; - border-right-width: 0; - border-bottom-width: 0; - border-color: #ddd; -} -table.m-table tr:first-child th, -table.m-table tr:first-child td { - vertical-align: top; - border-style: solid; - border-top-width: 0.0625rem; - border-left-width: 0; - border-right-width: 0; - border-bottom-width: 0; - border-color: #ddd; -} -table.m-table tr:last-child th, -table.m-table tr:last-child td { - vertical-align: top; - border-style: solid; - border-top-width: 0.0625rem; - border-bottom-width: 0.0625rem; - border-left-width: 0; - border-right-width: 0; - border-color: #ddd; -} -table.m-table caption { - padding-bottom: 0.5rem; -} -table.m-table thead tr:first-child th, -table.m-table thead tr:first-child td { - border-top-width: 0.125rem; - border-left-width: 0; - border-right-width: 0; -} -table.m-table thead th, -table.m-table thead td { - border-bottom-width: 0.125rem; - vertical-align: bottom; - border-left-width: 0; - border-right-width: 0; -} -table.m-table tfoot th, -table.m-table tfoot td { - border-top-width: 0.125rem; -} -table.m-table th, -table.m-table td { - padding: 0.5rem; -} -table.m-table.m-big th, -table.m-table.m-big td { - padding: 0.75rem 1rem; -} -table.m-table th { - text-align: left; -} -table.m-table th.m-thin { - font-weight: normal; -} -table.m-table td.m-default, -table.m-table th.m-default, -table.m-table td.m-primary, -table.m-table th.m-primary, -table.m-table td.m-success, -table.m-table th.m-success, -table.m-table td.m-warning, -table.m-table th.m-warning, -table.m-table td.m-danger, -table.m-table th.m-danger, -table.m-table td.m-info, -table.m-table th.m-info, -table.m-table td.m-dim, -table.m-table th.m-dim, -table.m-table td.m-param, -table.m-table th.m-param { - padding-left: 0.4375rem; - padding-right: 0.4375rem; -} -table.m-table.m-big td.m-default, -table.m-table.m-big th.m-default, -table.m-table.m-big td.m-primary, -table.m-table.m-big th.m-primary, -table.m-table.m-big td.m-success, -table.m-table.m-big th.m-success, -table.m-table.m-big td.m-warning, -table.m-table.m-big th.m-warning, -table.m-table.m-big td.m-danger, -table.m-table.m-big th.m-danger, -table.m-table.m-big td.m-info, -table.m-table.m-big th.m-info, -table.m-table.m-big td.m-dim, -table.m-table.m-big th.m-dim, -table.m-table.m-big td.m-param, -table.m-table.m-big th.m-param { - padding-left: 0.9375rem; - padding-right: 0.9375rem; -} -table.m-table tr.m-default td, -table.m-table td.m-default, -table.m-table tr.m-default th, -table.m-table th.m-default, -table.m-table tr.m-primary td, -table.m-table td.m-primary, -table.m-table tr.m-primary th, -table.m-table th.m-primary, -table.m-table tr.m-success td, -table.m-table td.m-success, -table.m-table tr.m-success th, -table.m-table th.m-success, -table.m-table tr.m-warning td, -table.m-table td.m-warning, -table.m-table tr.m-warning th, -table.m-table th.m-warning, -table.m-table tr.m-danger td, -table.m-table td.m-danger, -table.m-table tr.m-danger th, -table.m-table th.m-danger, -table.m-table tr.m-info td, -table.m-table td.m-info, -table.m-table tr.m-info th, -table.m-table th.m-info, -table.m-table tr.m-dim td, -table.m-table td.m-dim, -table.m-table tr.m-dim th, -table.m-table th.m-dim, -table.m-table tr.m-param td, -table.m-table td.m-param, -table.m-table tr.m-param th, -table.m-table th.m-param { - border-color: #e8e8e8; -} -.m-note pre, -.m-note code, -table.m-table tr.m-default pre, -table.m-table tr.m-default code, -table.m-table td.m-default pre, -table.m-table td.m-default code, -table.m-table th.m-default pre, -table.m-table th.m-default code, -table.m-table tr.m-primary pre, -table.m-table tr.m-primary code, -table.m-table td.m-primary pre, -table.m-table td.m-primary code, -table.m-table th.m-primary pre, -table.m-table th.m-primary code, -table.m-table tr.m-success pre, -table.m-table tr.m-success code, -table.m-table td.m-success pre, -table.m-table td.m-success code, -table.m-table th.m-success pre, -table.m-table th.m-success code, -table.m-table tr.m-warning pre, -table.m-table tr.m-warning code, -table.m-table td.m-warning pre, -table.m-table td.m-warning code, -table.m-table th.m-warning pre, -table.m-table th.m-warning code, -table.m-table tr.m-danger pre, -table.m-table tr.m-danger code, -table.m-table td.m-danger pre, -table.m-table td.m-danger code, -table.m-table th.m-danger pre, -table.m-table th.m-danger code, -table.m-table tr.m-info pre, -table.m-table tr.m-info code, -table.m-table td.m-info pre, -table.m-table td.m-info code, -table.m-table th.m-info pre, -table.m-table th.m-info code, -table.m-table tr.m-dim pre, -table.m-table tr.m-dim code, -table.m-table td.m-dim pre, -table.m-table td.m-dim code, -table.m-table th.m-dim pre, -table.m-table th.m-dim code, -table.m-table tr.m-param pre, -table.m-table tr.m-param code, -table.m-table td.m-param pre, -table.m-table td.m-param code, -table.m-table th.m-param pre, -table.m-table th.m-param code { - background-color: rgba(251, 240, 236, 0.5); -} -img.m-image, -svg.m-image { - display: block; - margin-left: auto; - margin-right: auto; -} -div.m-image { - text-align: center; -} -img.m-image, -svg.m-image, -div.m-image img, -div.m-image svg { - max-width: 100%; - border-radius: 0px; -} -div.m-image.m-fullwidth img, -div.m-image.m-fullwidth svg { - width: 100%; -} -img.m-image.m-badge, -div.m-image.m-badge img { - border-radius: 50%; -} -figure.m-figure { - max-width: 100%; - margin-top: 0; - margin-left: auto; - margin-right: auto; - position: relative; - display: table; -} -figure.m-figure::before { - position: absolute; - content: " "; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: -1; - border-style: solid; - border-width: 0.125rem; - border-radius: 0px; - border-color: #ddd; -} -figure.m-figure.m-flat::before { - border-color: transparent; -} -figure.m-figure > * { - margin-left: 1rem; - margin-right: 1rem; - display: table-caption; - caption-side: bottom; -} -figure.m-figure > *:first-child { - display: inline; -} -figure.m-figure > *:last-child { - margin-bottom: 1rem !important; -} -figure.m-figure img, -figure.m-figure svg { - position: relative; - margin-left: 0; - margin-right: 0; - margin-bottom: 0; - border-top-left-radius: 0px; - border-top-right-radius: 0px; - max-width: 100%; -} -figure.m-figure.m-flat img, -figure.m-figure.m-flat svg { - border-bottom-left-radius: 0px; - border-bottom-right-radius: 0px; -} -figure.m-figure a img, -figure.m-figure a svg { - margin-left: -1rem; - margin-right: -1rem; -} -figure.m-figure.m-fullwidth, -figure.m-figure.m-fullwidth > * { - display: block; -} -figure.m-figure.m-fullwidth > *:first-child { - display: inline; -} -figure.m-figure.m-fullwidth img, -figure.m-figure.m-fullwidth svg { - width: 100%; -} -figure.m-figure.m-fullwidth::after { - content: " "; - display: block; - margin-top: 1rem; - height: 1px; -} -.m-code-figure, -.m-console-figure { - margin-top: 0; - margin-left: 0; - margin-right: 0; - position: relative; - padding: 1rem; -} -.m-code-figure::before, -.m-console-figure::before { - position: absolute; - content: " "; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: -1; - border-style: solid; - border-width: 0.125rem; - border-radius: 0px; -} -.m-code-figure::before { - border-color: #f7f7f7; -} -.m-console-figure::before { - border-color: #f7f7f7; -} -.m-code-figure.m-flat::before, -.m-console-figure.m-flat::before { - border-color: transparent; -} -.m-code-figure > pre:first-child, -.m-console-figure > pre:first-child { - position: relative; - margin: -1rem -1rem 1rem -1rem; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} -.m-code-figure > pre.m-nopad, -.m-console-figure > pre.m-nopad { - margin-left: -0.875rem; - margin-right: -0.875rem; - margin-top: -1rem; - margin-bottom: -0.875rem; - padding-left: 0.875rem; -} -figure.m-figure figcaption, -.m-code-figure figcaption, -.m-console-figure figcaption { - margin-top: 0.5rem; - margin-bottom: 0.5rem; - font-weight: 300; - font-size: 1.17rem; -} -figure.m-figure figcaption a, -.m-code-figure figcaption a, -.m-console-figure figcaption a { - text-decoration: none; -} -figure.m-figure figcaption .m-figure-description { - margin-top: 0.5rem; - font-weight: normal; - font-size: 1rem; -} -figure.m-figure figcaption .m-figure-description a { - text-decoration: underline; -} -.m-imagegrid > div { - background-color: #e8e8e8; -} -.m-imagegrid > div > figure { - display: block; - float: left; - position: relative; - margin: 0; -} -.m-imagegrid > div > figure > div, -.m-imagegrid > div > figure > figcaption, -.m-imagegrid > div > figure > a > div, -.m-imagegrid > div > figure > a > figcaption { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - border-color: #e8e8e8; - border-style: solid; - border-width: 0.25rem; - padding: 0.5rem; -} -.m-imagegrid > div > figure:first-child > div, -.m-imagegrid > div > figure:first-child > figcaption, -.m-imagegrid > div > figure:first-child > a > div, -.m-imagegrid > div > figure:first-child > a > figcaption { - border-left-width: 0; -} -.m-imagegrid > div > figure:last-child > div, -.m-imagegrid > div > figure:last-child > figcaption, -.m-imagegrid > div > figure:last-child > a > div, -.m-imagegrid > div > figure:last-child > a > figcaption { - border-right-width: 0; -} -.m-imagegrid > div > figure > figcaption, -.m-imagegrid > div > figure > a > figcaption { - color: transparent; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - font-size: 0.75rem; -} -.m-imagegrid > div > figure > div::before, -.m-imagegrid > div > figure > figcaption::before, -.m-imagegrid > div > figure > a > div::before, -.m-imagegrid > div > figure > a > figcaption::before { - content: ""; - display: inline-block; - height: 100%; - vertical-align: bottom; - width: 0; -} -.m-imagegrid > div > figure:hover > figcaption, -.m-imagegrid > div > figure:hover > a > figcaption { - background: linear-gradient( - transparent 0%, - transparent 75%, - rgba(0, 0, 0, 0.85) 100% - ); - color: #ffffff; -} -.m-imagegrid > div > figure > img, -.m-imagegrid > div > figure > a > img { - width: 100%; - height: 100%; -} -.m-imagegrid > div::after { - display: block; - content: " "; - clear: both; -} -@media screen and (max-width: 767px) { - .m-imagegrid > div > figure { - float: none; - width: 100% !important; - } - .m-imagegrid > div > figure > div, - .m-imagegrid > div > figure > figcaption, - .m-imagegrid > div > figure > a > div, - .m-imagegrid > div > figure > a > figcaption { - border-left-width: 0; - border-right-width: 0; - } -} -.m-container-inflatable > .m-row > [class*="m-col-"] > .m-note, -.m-container-inflatable > .m-row > [class*="m-col-"] > .m-frame, -.m-container-inflatable > .m-row > [class*="m-col-"] > .m-block, -.m-container-inflatable > .m-row > [class*="m-col-"] > .m-imagegrid, -.m-container-inflatable > .m-row > [class*="m-col-"] > pre, -.m-container-inflatable > .m-row > [class*="m-col-"] > .m-code-figure, -.m-container-inflatable > .m-row > [class*="m-col-"] > .m-console-figure, -.m-container-inflatable > .m-row > [class*="m-col-"] section > .m-note, -.m-container-inflatable > .m-row > [class*="m-col-"] section > .m-frame, -.m-container-inflatable > .m-row > [class*="m-col-"] section > .m-block, -.m-container-inflatable > .m-row > [class*="m-col-"] section > .m-imagegrid, -.m-container-inflatable > .m-row > [class*="m-col-"] section > pre, -.m-container-inflatable > .m-row > [class*="m-col-"] section > .m-code-figure, -.m-container-inflatable > .m-row > [class*="m-col-"] section > .m-console-figure, -.m-container-inflatable [class*="m-center-"] > .m-note, -.m-container-inflatable [class*="m-center-"] > .m-frame, -.m-container-inflatable [class*="m-center-"] > .m-block, -.m-container-inflatable [class*="m-center-"] > .m-imagegrid, -.m-container-inflatable [class*="m-center-"] > pre, -.m-container-inflatable [class*="m-center-"] > .m-code-figure, -.m-container-inflatable [class*="m-center-"] > .m-console-figure, -.m-container-inflatable [class*="m-left-"] > .m-note, -.m-container-inflatable [class*="m-left-"] > .m-frame, -.m-container-inflatable [class*="m-left-"] > .m-block, -.m-container-inflatable [class*="m-left-"] > .m-imagegrid, -.m-container-inflatable [class*="m-left-"] > pre, -.m-container-inflatable [class*="m-left-"] > .m-code-figure, -.m-container-inflatable [class*="m-left-"] > .m-console-figure, -.m-container-inflatable [class*="m-right-"] > .m-note, -.m-container-inflatable [class*="m-right-"] > .m-frame, -.m-container-inflatable [class*="m-right-"] > .m-block, -.m-container-inflatable [class*="m-right-"] > .m-imagegrid, -.m-container-inflatable [class*="m-right-"] > pre, -.m-container-inflatable [class*="m-right-"] > .m-code-figure, -.m-container-inflatable [class*="m-right-"] > .m-console-figure, -.m-container-inflatable .m-container-inflate > .m-note, -.m-container-inflatable .m-container-inflate > .m-frame, -.m-container-inflatable .m-container-inflate > .m-block, -.m-container-inflatable .m-container-inflate > .m-imagegrid, -.m-container-inflatable .m-container-inflate > pre, -.m-container-inflatable .m-container-inflate > .m-code-figure, -.m-container-inflatable .m-container-inflate > .m-console-figure { - margin-left: -1rem; - margin-right: -1rem; -} -@media screen and (min-width: 576px) { - .m-container-inflatable .m-center-s > .m-note, - .m-container-inflatable .m-center-s > .m-frame, - .m-container-inflatable .m-center-s > .m-block, - .m-container-inflatable .m-center-s > .m-imagegrid, - .m-container-inflatable .m-center-s > pre, - .m-container-inflatable .m-center-s > .m-code-figure, - .m-container-inflatable .m-center-s > .m-console-figure { - margin-left: -1rem; - margin-right: -1rem; - } - .m-container-inflatable .m-left-s > .m-note, - .m-container-inflatable .m-left-s > .m-frame, - .m-container-inflatable .m-left-s > .m-block, - .m-container-inflatable .m-left-s > .m-imagegrid, - .m-container-inflatable .m-left-s > pre, - .m-container-inflatable .m-left-s > .m-code-figure, - .m-container-inflatable .m-left-s > .m-console-figure { - margin-left: -1rem; - margin-right: 0; - } - .m-container-inflatable .m-right-s > .m-note, - .m-container-inflatable .m-right-s > .m-frame, - .m-container-inflatable .m-right-s > .m-block, - .m-container-inflatable .m-right-s > .m-imagegrid, - .m-container-inflatable .m-right-s > pre, - .m-container-inflatable .m-right-s > .m-code-figure, - .m-container-inflatable .m-right-s > .m-console-figure { - margin-left: 0; - margin-right: -1rem; - } - .m-container-inflatable - > .m-row - > .m-col-s-10 - > .m-imagegrid.m-container-inflate, - .m-container-inflatable - > .m-row - > .m-col-s-10 - section - > .m-imagegrid.m-container-inflate { - margin-left: -10%; - margin-right: -10%; - } -} -@media screen and (min-width: 768px) { - .m-container-inflatable .m-center-m > .m-note, - .m-container-inflatable .m-center-m > .m-frame, - .m-container-inflatable .m-center-m > .m-block, - .m-container-inflatable .m-center-m > .m-imagegrid, - .m-container-inflatable .m-center-m > pre, - .m-container-inflatable .m-center-m > .m-code-figure, - .m-container-inflatable .m-center-m > .m-console-figure { - margin-left: -1rem; - margin-right: -1rem; - } - .m-container-inflatable .m-left-m > .m-note, - .m-container-inflatable .m-left-m > .m-frame, - .m-container-inflatable .m-left-m > .m-block, - .m-container-inflatable .m-left-m > .m-imagegrid, - .m-container-inflatable .m-left-m > pre, - .m-container-inflatable .m-left-m > .m-code-figure, - .m-container-inflatable .m-left-m > .m-console-figure { - margin-left: -1rem; - margin-right: 0; - } - .m-container-inflatable .m-right-m > .m-note, - .m-container-inflatable .m-right-m > .m-frame, - .m-container-inflatable .m-right-m > .m-block, - .m-container-inflatable .m-right-m > .m-imagegrid, - .m-container-inflatable .m-right-m > pre, - .m-container-inflatable .m-right-m > .m-code-figure, - .m-container-inflatable .m-right-m > .m-console-figure { - margin-left: 0; - margin-right: -1rem; - } - .m-container-inflatable - > .m-row - > .m-col-m-10 - > .m-imagegrid.m-container-inflate, - .m-container-inflatable - > .m-row - > .m-col-m-10 - section - > .m-imagegrid.m-container-inflate { - margin-left: -10%; - margin-right: -10%; - } -} -@media screen and (min-width: 992px) { - .m-container-inflatable .m-center-l > .m-note, - .m-container-inflatable .m-center-l > .m-frame, - .m-container-inflatable .m-center-l > .m-block, - .m-container-inflatable .m-center-l > .m-imagegrid, - .m-container-inflatable .m-center-l > pre, - .m-container-inflatable .m-center-l > .m-code-figure, - .m-container-inflatable .m-center-l > .m-console-figure { - margin-left: -1rem; - margin-right: -1rem; - } - .m-container-inflatable .m-left-l > .m-note, - .m-container-inflatable .m-left-l > .m-frame, - .m-container-inflatable .m-left-l > .m-block, - .m-container-inflatable .m-left-l > .m-imagegrid, - .m-container-inflatable .m-left-l > pre, - .m-container-inflatable .m-left-l > .m-code-figure, - .m-container-inflatable .m-left-l > .m-console-figure { - margin-left: -1rem; - margin-right: 0; - } - .m-container-inflatable .m-right-l > .m-note, - .m-container-inflatable .m-right-l > .m-frame, - .m-container-inflatable .m-right-l > .m-block, - .m-container-inflatable .m-right-l > .m-imagegrid, - .m-container-inflatable .m-right-l > pre, - .m-container-inflatable .m-right-l > .m-code-figure, - .m-container-inflatable .m-right-l > .m-console-figure { - margin-left: 0; - margin-right: -1rem; - } - .m-container-inflatable - > .m-row - > .m-col-l-10 - > .m-imagegrid.m-container-inflate, - .m-container-inflatable - > .m-row - > .m-col-l-10 - section - > .m-imagegrid.m-container-inflate { - margin-left: -10%; - margin-right: -10%; - } -} -pre.m-code span.hll { - margin-left: -1rem; - margin-right: -1rem; - padding-left: 1rem; -} -.m-code.m-inverted > span, -.m-console.m-inverted > span { - opacity: 0.3333; -} -.m-code.m-inverted > span.hll, -.m-console.m-inverted > span.hll { - opacity: 1; - background-color: transparent; - border-color: transparent; -} -.m-code.m-inverted { - color: rgba(91, 91, 91, 0.33); -} -.m-console.m-inverted { - color: rgba(91, 91, 91, 0.33); -} -.m-code.m-inverted > span.hll { - color: #000000; -} -.m-cosole.m-inverted > span.hll { - color: #000000; -} -.m-code-color { - display: inline-block; - width: 0.75rem; - height: 0.75rem; - vertical-align: -0.05rem; - margin-left: 0.2rem; - margin-right: 0.1rem; - border-radius: 0px; -} -div.m-math { - overflow-x: auto; - overflow-y: hidden; -} -div.m-math svg { - margin-left: auto; - margin-right: auto; - display: block; -} -div.m-button a svg.m-math { - fill: #ffffff; -} -div.m-button.m-flat a svg.m-math { - fill: #000000; -} -div.m-button.m-flat a:hover svg.m-math, -div.m-button.m-default a:focus svg.m-math, -div.m-button.m-default a:active svg.m-math { - fill: #26a9e0; -} -.m-graph { - font-size: 14px; -} -div.m-plot svg, -div.m-graph svg { - max-width: 100%; - margin-left: auto; - margin-right: auto; - display: block; -} -div.m-plot .m-background { - fill: #fbf0ec; -} -div.m-plot svg .m-label { - font-size: 11px; -} -div.m-plot svg .m-title { - font-size: 13px; -} -div.m-plot svg .m-label, -div.m-plot svg .m-title { - fill: #000000; -} -div.m-plot svg .m-line { - stroke: #000000; - stroke-width: 0.8; -} -div.m-plot svg .m-error { - stroke: #000000; - stroke-width: 1.5; -} -div.m-plot svg .m-label.m-dim { - fill: #666; -} -.m-graph g.m-edge path, -.m-graph g.m-cluster polygon, -.m-graph g.m-node.m-flat ellipse, -.m-graph g.m-node.m-flat polygon { - fill: none; -} -.m-graph g.m-node:not(.m-flat) text { - fill: #ffffff; -} -figure.m-figure > svg.m-math:first-child, -figure.m-figure > svg.m-graph:first-child { - padding: 1rem; - box-sizing: content-box; -} -figure.m-figure:not(.m-flat) > svg.m-math:first-child, -figure.m-figure:not(.m-flat) > svg.m-graph:first-child { - background-color: #ddd; -} -.m-block.m-default { - border-left-color: #ddd; -} -.m-block.m-default h3, -.m-block.m-default h4, -.m-block.m-default h5, -.m-block.m-default h6, -.m-text.m-default, -.m-label.m-flat.m-default { - color: #000000; -} -.m-block.m-default h3 a, -.m-block.m-default h4 a, -.m-block.m-default h5 a, -.m-block.m-default h6 a { - color: #26a9e0; -} -.m-block.m-primary { - border-left-color: #31708f; -} -.m-block.m-primary h3, -.m-block.m-primary h4, -.m-block.m-primary h5, -.m-block.m-primary h6, -.m-block.m-primary h3 a, -.m-block.m-primary h4 a, -.m-block.m-primary h5 a, -.m-block.m-primary h6 a, -.m-text.m-primary, -.m-label.m-flat.m-primary { - color: #31708f; -} -.m-block.m-success { - border-left-color: #9ad36a; -} -.m-block.m-success h3, -.m-block.m-success h4, -.m-block.m-success h5, -.m-block.m-success h6, -.m-block.m-success h3 a, -.m-block.m-success h4 a, -.m-block.m-success h5 a, -.m-block.m-success h6 a, -.m-text.m-success, -.m-label.m-flat.m-success { - color: #9ad36a; -} -.m-block.m-warning { - border-left-color: #f9cf79; -} -.m-block.m-warning h3, -.m-block.m-warning h4, -.m-block.m-warning h5, -.m-block.m-warning h6, -.m-block.m-warning h3 a, -.m-block.m-warning h4 a, -.m-block.m-warning h5 a, -.m-block.m-warning h6 a, -.m-text.m-warning, -.m-label.m-flat.m-warning { - color: #f9cf79; -} -.m-block.m-danger { - border-left-color: #f60000; -} -.m-block.m-danger h3, -.m-block.m-danger h4, -.m-block.m-danger h5, -.m-block.m-danger h6, -.m-block.m-danger h3 a, -.m-block.m-danger h4 a, -.m-block.m-danger h5 a, -.m-block.m-danger h6 a, -.m-text.m-danger, -.m-label.m-flat.m-danger { - color: #f60000; -} -.m-block.m-info { - border-left-color: #31708f; -} -.m-block.m-info h3, -.m-block.m-info h4, -.m-block.m-info h5, -.m-block.m-info h6, -.m-block.m-info h3 a, -.m-block.m-info h4 a, -.m-block.m-info h5 a, -.m-block.m-info h6 a, -.m-text.m-info, -.m-label.m-flat.m-info { - color: #31708f; -} -.m-block.m-param h3, -.m-block.m-param h4, -.m-block.m-param h5, -.m-block.m-param h6, -.m-block.m-param h3 a, -.m-block.m-param h4 a, -.m-block.m-param h5 a, -.m-block.m-param h6 a, -.m-text.m-param, -.m-label.m-flat.m-param { - color: #9ad36a; -} -.m-block.m-dim { - border-left-color: #666; -} -span.m-default { - color: #000000; - background-color: transparent; -} -span.m-default a { - color: var(--default-link-color); - background-color: transparent; -} -span.m-default a:hover, -span.m-default a:focus, -span.m-default a:active { - color: #26a9e0; - background-color: transparent; -} -span.m-primary { - color: #31708f; - background-color: transparent; -} -span.m-primary a { - color: var(--primary-link-color); - background-color: transparent; -} -span.m-primary a:hover, -span.m-primary a:focus, -span.m-primary a:active { - color: #31708f; - background-color: transparent; -} -span.m-success { - color: #9ad36a; - background-color: transparent; -} -span.m-success a { - color: var(--success-link-color); - background-color: transparent; -} -span.m-success a:hover, -span.m-success a:focus, -span.m-success a:active { - color: #9ad36a; - background-color: transparent; -} -span.m-warning { - color: #f9cf79; - background-color: transparent; -} -span.m-warning a { - color: var(--warning-link-color); - background-color: transparent; -} -span.m-warning a:hover, -span.m-warning a:focus, -span.m-warning a:active { - color: #f9cf79; - background-color: transparent; -} -span.m-danger { - color: #f60000; - background-color: transparent; -} -span.m-danger a { - color: var(--danger-link-color); - background-color: transparent; -} -span.m-danger a:hover, -span.m-danger a:focus, -span.m-danger a:active { - color: #f60000; - background-color: transparent; -} -span.m-info { - color: #31708f; - background-color: transparent; -} -span.m-info a { - color: var(--info-link-color); - background-color: transparent; -} -span.m-info a:hover, -span.m-info a:focus, -span.m-info a:active { - color: #67cce0; - background-color: transparent; -} -span.m-param { - color: #9ad36a; - background-color: transparent; - font-weight: bold; -} -span.m-param a { - color: var(--param-link-color); - background-color: transparent; -} -span.m-param a:hover, -span.m-param a:focus, -span.m-param a:active { - color: #9ad36a; - background-color: transparent; -} -span.m-dim { - color: #666; - background-color: transparent; -} -span.m-dim a { - color: #949494; - background-color: transparent; -} -span.m-dim a:hover, -span.m-dim a:focus, -span.m-dim a:active { - color: #949494; - background-color: transparent; -} -.m-block.m-dim, -.m-text.m-dim, -.m-label.m-flat.m-dim { - color: #666; -} -.m-block.m-dim a, -.m-text.m-dim a { - color: #949494; -} -.m-block.m-dim a:hover, -.m-block.m-dim a:focus, -.m-block.m-dim a:active, -.m-text.m-dim a:hover, -.m-text.m-dim a:focus, -.m-text.m-dim a:active { - color: #949494; -} -.m-block.m-param { - border-left-color: #9ad36a; -} -.m-block.m-param h3, -.m-block.m-param h4, -.m-block.m-param h5, -.m-block.m-param h6, -.m-block.m-param h3 a, -.m-block.m-param h4 a, -.m-block.m-param h5 a, -.m-block.m-param h6 a, -.m-text.m-param, -.m-label.m-flat.m-param { - color: #9ad36a; -} -.m-block.m-flat { - border-color: transparent; -} -.m-block.m-flat h3, -.m-block.m-flat h4, -.m-block.m-flat h5, -.m-block.m-flat h6 { - color: #000000; -} -.m-block.m-default h3 a:hover, -.m-block.m-default h3 a:focus, -.m-block.m-default h3 a:active, -.m-block.m-default h4 a:hover, -.m-block.m-default h4 a:focus, -.m-block.m-default h4 a:active, -.m-block.m-default h5 a:hover, -.m-block.m-default h5 a:focus, -.m-block.m-default h5 a:active, -.m-block.m-default h6 a:hover, -.m-block.m-default h6 a:focus, -.m-block.m-default h6 a:active { - color: #26a9e0; -} -.m-block.m-primary h3 a:hover, -.m-block.m-primary h3 a:focus, -.m-block.m-primary h3 a:active, -.m-block.m-primary h4 a:hover, -.m-block.m-primary h4 a:focus, -.m-block.m-primary h4 a:active, -.m-block.m-primary h5 a:hover, -.m-block.m-primary h5 a:focus, -.m-block.m-primary h5 a:active, -.m-block.m-primary h6 a:hover, -.m-block.m-primary h6 a:focus, -.m-block.m-primary h6 a:active { - color: #31708f; -} -.m-block.m-success h3 a:hover, -.m-block.m-success h3 a:focus, -.m-block.m-success h3 a:active, -.m-block.m-success h4 a:hover, -.m-block.m-success h4 a:focus, -.m-block.m-success h4 a:active, -.m-block.m-success h5 a:hover, -.m-block.m-success h5 a:focus, -.m-block.m-success h5 a:active, -.m-block.m-success h6 a:hover, -.m-block.m-success h6 a:focus, -.m-block.m-success h6 a:active { - color: #9ad36a; -} -.m-block.m-warning h3 a:hover, -.m-block.m-warning h3 a:focus, -.m-block.m-warning h3 a:active, -.m-block.m-warning h4 a:hover, -.m-block.m-warning h4 a:focus, -.m-block.m-warning h4 a:active, -.m-block.m-warning h5 a:hover, -.m-block.m-warning h5 a:focus, -.m-block.m-warning h5 a:active, -.m-block.m-warning h6 a:hover, -.m-block.m-warning h6 a:focus, -.m-block.m-warning h6 a:active { - color: #f9cf79; -} -.m-block.m-danger h3 a:hover, -.m-block.m-danger h3 a:focus, -.m-block.m-danger h3 a:active, -.m-block.m-danger h4 a:hover, -.m-block.m-danger h4 a:focus, -.m-block.m-danger h4 a:active, -.m-block.m-danger h5 a:hover, -.m-block.m-danger h5 a:focus, -.m-block.m-danger h5 a:active, -.m-block.m-danger h6 a:hover, -.m-block.m-danger h6 a:focus, -.m-block.m-danger h6 a:active { - color: #f60000; -} -.m-block.m-info h3 a:hover, -.m-block.m-info h3 a:focus, -.m-block.m-info h3 a:active, -.m-block.m-info h4 a:hover, -.m-block.m-info h4 a:focus, -.m-block.m-info h4 a:active, -.m-block.m-info h5 a:hover, -.m-block.m-info h5 a:focus, -.m-block.m-info h5 a:active, -.m-block.m-info h6 a:hover, -.m-block.m-info h6 a:focus, -.m-block.m-info h6 a:active { - color: #67cce0; -} -.m-block.m-param h3 a:hover, -.m-block.m-param h3 a:focus, -.m-block.m-param h3 a:active, -.m-block.m-param h4 a:hover, -.m-block.m-param h4 a:focus, -.m-block.m-param h4 a:active, -.m-block.m-param h5 a:hover, -.m-block.m-param h5 a:focus, -.m-block.m-param h5 a:active, -.m-block.m-param h6 a:hover, -.m-block.m-param h6 a:focus, -.m-block.m-param h6 a:active { - color: #9ad36a; -} -div.m-button a, -.m-label { - color: #ffffff; -} -div.m-button.m-flat a { - color: #000000; -} -div.m-button.m-flat a:hover, -div.m-button.m-default a:focus, -div.m-button.m-default a:active { - color: #26a9e0; -} -div.m-button.m-default a, -.m-label:not(.m-flat).m-default { - background-color: #000000; - color: #353535; -} -div.m-button.m-primary a, -.m-label:not(.m-flat).m-primary { - background-color: #31708f; - color: #67cce0; -} -div.m-button.m-success a, -.m-label:not(.m-flat).m-success { - background-color: #9ad36a; - color: #3c763d; -} -div.m-button.m-warning a, -.m-label:not(.m-flat).m-warning { - background-color: #f9cf79; - color: #8a6d3b; -} -div.m-button.m-danger a, -.m-label:not(.m-flat).m-danger { - background-color: #f60000; - color: #920000; -} -div.m-button.m-info a, -.m-label:not(.m-flat).m-info { - background-color: #31708f; - color: #81bcda; -} -div.m-button.m-dim a, -.m-label:not(.m-flat).m-dim { - background-color: #666; - color: #7c7c7c; -} -div.m-button.m-param a, -.m-label:not(.m-flat).m-param { - background-color: #9ad36a; - color: #3c763d; -} -div.m-button.m-default a:hover, -div.m-button.m-default a:focus, -div.m-button.m-default a:active { - background-color: #26a9e0; -} -div.m-button.m-primary a:hover, -div.m-button.m-primary a:focus, -div.m-button.m-primary a:active { - background-color: #31708f; -} -div.m-button.m-success a:hover, -div.m-button.m-success a:focus, -div.m-button.m-success a:active { - background-color: #9ad36a; -} -div.m-button.m-warning a:hover, -div.m-button.m-warning a:focus, -div.m-button.m-warning a:active { - background-color: #f9cf79; -} -div.m-button.m-danger a:hover, -div.m-button.m-danger a:focus, -div.m-button.m-danger a:active { - background-color: #f60000; -} -div.m-button.m-info a:hover, -div.m-button.m-info a:focus, -div.m-button.m-info a:active { - background-color: #67cce0; -} -div.m-button.m-dim a:hover, -div.m-button.m-dim a:focus, -div.m-button.m-dim a:active { - background-color: #c0c0c0; -} -div.m-button.m-param a:hover, -div.m-button.m-param a:focus, -div.m-button.m-param a:active { - background-color: #9ad36a; -} -.m-note.m-default { - background-color: transparent; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-default, -table.m-table tr.m-default td, -table.m-table td.m-default, -table.m-table tr.m-default th, -table.m-table th.m-default, -table.m-table tr.m-default strong, -table.m-table strong.m-default, -table.m-table tr.m-default em, -table.m-table em.m-default { - color: #353535; -} -.m-note.m-default a:hover, -table.m-table tr.m-default td a:hover, -table.m-table td.m-default a:hover, -table.m-table tr.m-default th a:hover, -table.m-table th.m-default a:hover, -.m-note.m-default a:focus, -table.m-table tr.m-default td a:focus, -table.m-table td.m-default a:focus, -table.m-table tr.m-default th a:focus, -table.m-table th.m-default a:focus, -.m-note.m-default a:active, -table.m-table tr.m-default td a:active, -table.m-table td.m-default a:active, -table.m-table tr.m-default th a:active, -table.m-table th.m-default a:active { - color: #26a9e0; -} -.m-note.m-primary { - border-color: #31708f; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-primary a, -table.m-table tr.m-primary td a, -table.m-table td.m-primary a, -table.m-table tr.m-primary th a, -table.m-table th.m-primary a { - color: #26a9e0; -} -.m-note.m-primary, -table.m-table tr.m-primary td, -table.m-table td.m-primary, -table.m-table tr.m-primary th, -table.m-table th.m-primary, -table.m-table tr.m-primary strong, -table.m-table strong.m-primary, -table.m-table tr.m-primary em, -table.m-table em.m-primary { - background-color: transparent; - color: #67cce0; -} -.m-note.m-primary a, -table.m-table tr.m-primary td a, -table.m-table td.m-primary a, -table.m-table tr.m-primary th a, -table.m-table th.m-primary a { - color: #31708f; -} -.m-note.m-primary a:hover, -table.m-table tr.m-primary td a:hover, -table.m-table td.m-primary a:hover, -table.m-table tr.m-primary th a:hover, -table.m-table th.m-primary a:hover, -.m-note.m-primary a:focus, -table.m-table tr.m-primary td a:focus, -table.m-table td.m-primary a:focus, -table.m-table tr.m-primary th a:focus, -table.m-table th.m-primary a:focus, -.m-note.m-primary a:active, -table.m-table tr.m-primary td a:active, -table.m-table td.m-primary a:active, -table.m-table tr.m-primary th a:active, -table.m-table th.m-primary a:active { - color: #31708f; -} -.m-note.m-success { - border-color: #9ad36a; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-success, -table.m-table tr.m-success td, -table.m-table td.m-success, -table.m-table tr.m-success th, -table.m-table th.m-success, -table.m-table tr.m-success strong, -table.m-table strong.m-success, -table.m-table tr.m-success em, -table.m-table em.m-success { - background-color: transparent; - color: #3c763d; -} -.m-note.m-success a, -table.m-table tr.m-success td a, -table.m-table td.m-success a, -table.m-table tr.m-success th a, -table.m-table th.m-success a { - color: #9ad36a; -} -.m-note.m-success a:hover, -table.m-table tr.m-success td a:hover, -table.m-table td.m-success a:hover, -table.m-table tr.m-success th a:hover, -table.m-table th.m-success a:hover, -.m-note.m-success a:focus, -table.m-table tr.m-success td a:focus, -table.m-table td.m-success a:focus, -table.m-table tr.m-success th a:focus, -table.m-table th.m-success a:focus, -.m-note.m-success a:active, -table.m-table tr.m-success td a:active, -table.m-table td.m-success a:active, -table.m-table tr.m-success th a:active, -table.m-table th.m-success a:active { - color: #9ad36a; -} -.m-note.m-warning { - border-color: #f9cf79; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-warning, -table.m-table tr.m-warning td, -table.m-table td.m-warning, -table.m-table tr.m-warning th, -table.m-table th.m-warning, -table.m-table tr.m-warning strong, -table.m-table strong.m-warning, -table.m-table tr.m-warning em, -table.m-table em.m-warning { - background-color: transparent; - color: #8a6d3b; -} -.m-note.m-warning a, -table.m-table tr.m-warning td a, -table.m-table td.m-warning a, -table.m-table tr.m-warning th a, -table.m-table th.m-warning a { - color: #f9cf79; -} -.m-note.m-warning a:hover, -table.m-table tr.m-warning td a:hover, -table.m-table td.m-warning a:hover, -table.m-table tr.m-warning th a:hover, -table.m-table th.m-warning a:hover, -.m-note.m-warning a:focus, -table.m-table tr.m-warning td a:focus, -table.m-table td.m-warning a:focus, -table.m-table tr.m-warning th a:focus, -table.m-table th.m-warning a:focus, -.m-note.m-warning a:active, -table.m-table tr.m-warning td a:active, -table.m-table td.m-warning a:active, -table.m-table tr.m-warning th a:active, -table.m-table th.m-warning a:active { - color: #f9cf79; -} -.m-note.m-danger { - border-color: #f60000; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-danger, -table.m-table tr.m-danger td, -table.m-table td.m-danger, -table.m-table tr.m-danger th, -table.m-table th.m-danger, -table.m-table tr.m-danger strong, -table.m-table strong.m-danger, -table.m-table tr.m-danger em, -table.m-table em.m-danger { - background-color: transparent; - color: #920000; -} -.m-note.m-danger a, -table.m-table tr.m-danger td a, -table.m-table td.m-danger a, -table.m-table tr.m-danger th a, -table.m-table th.m-danger a { - color: #f60000; -} -.m-note.m-danger a:hover, -table.m-table tr.m-danger td a:hover, -table.m-table td.m-danger a:hover, -table.m-table tr.m-danger th a:hover, -table.m-table th.m-danger a:hover, -.m-note.m-danger a:focus, -table.m-table tr.m-danger td a:focus, -table.m-table td.m-danger a:focus, -table.m-table tr.m-danger th a:focus, -table.m-table th.m-danger a:focus, -.m-note.m-danger a:active, -table.m-table tr.m-danger td a:active, -table.m-table td.m-danger a:active, -table.m-table tr.m-danger th a:active, -table.m-table th.m-danger a:active { - color: #f60000; -} -.m-note.m-info { - border-color: #31708f; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-info, -table.m-table tr.m-info td, -table.m-table td.m-info, -table.m-table tr.m-info th, -table.m-table th.m-info, -table.m-table tr.m-info strong, -table.m-table strong.m-info, -table.m-table tr.m-info em, -table.m-table em.m-info { - background-color: transparent; - color: #81bcda; -} -.m-note.m-info a, -table.m-table tr.m-info td a, -table.m-table td.m-info a, -table.m-table tr.m-info th a, -table.m-table th.m-info a { - color: #67cce0; -} -.m-note.m-info a:hover, -table.m-table tr.m-info td a:hover, -table.m-table td.m-info a:hover, -table.m-table tr.m-info th a:hover, -table.m-table th.m-info a:hover, -.m-note.m-info a:focus, -table.m-table tr.m-info td a:focus, -table.m-table td.m-info a:focus, -table.m-table tr.m-info th a:focus, -table.m-table th.m-info a:focus, -.m-note.m-info a:active, -table.m-table tr.m-info td a:active, -table.m-table td.m-info a:active, -table.m-table tr.m-info th a:active, -table.m-table th.m-info a:active { - color: #67cce0; -} -.m-note.m-dim { - border-color: #666; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-dim, -table.m-table tr.m-dim td, -table.m-table td.m-dim, -table.m-table tr.m-dim th, -table.m-table th.m-dim, -table.m-table tr.m-dim strong, -table.m-table strong.m-dim, -table.m-table tr.m-dim em, -table.m-table em.m-dim { - background-color: transparent; - color: #7c7c7c; -} -.m-note.m-dim a, -table.m-table tr.m-dim td a, -table.m-table td.m-dim a, -table.m-table tr.m-dim th a, -table.m-table th.m-dim a { - color: #c0c0c0; -} -.m-note.m-dim a:hover, -table.m-table tr.m-dim td a:hover, -table.m-table td.m-dim a:hover, -table.m-table tr.m-dim th a:hover, -table.m-table th.m-dim a:hover, -.m-note.m-dim a:focus, -table.m-table tr.m-dim td a:focus, -table.m-table td.m-dim a:focus, -table.m-table tr.m-dim th a:focus, -table.m-table th.m-dim a:focus, -.m-note.m-dim a:active, -table.m-table tr.m-dim td a:active, -table.m-table td.m-dim a:active, -table.m-table tr.m-dim th a:active, -table.m-table th.m-dim a:active { - color: #c0c0c0; -} -.m-note.m-param { - border-color: #9ad36a; - border-width: 2px; - border-style: solid; - padding-top: 0; -} -.m-note.m-param, -table.m-table tr.m-param td, -table.m-table td.m-param, -table.m-table tr.m-param th, -table.m-table th.m-param, -table.m-table tr.m-param strong, -table.m-table strong.m-param, -table.m-table tr.m-param em, -table.m-table em.m-param { - background-color: transparent; - color: #3c763d; -} -.m-note.m-param a, -table.m-table tr.m-param td a, -table.m-table td.m-param a, -table.m-table tr.m-param th a, -table.m-table th.m-param a { - color: #9ad36a; -} -.m-note.m-param a:hover, -table.m-table tr.m-param td a:hover, -table.m-table td.m-param a:hover, -table.m-table tr.m-param th a:hover, -table.m-table th.m-param a:hover, -.m-note.m-param a:focus, -table.m-table tr.m-param td a:focus, -table.m-table td.m-param a:focus, -table.m-table tr.m-param th a:focus, -table.m-table th.m-param a:focus, -.m-note.m-param a:active, -table.m-table tr.m-param td a:active, -table.m-table td.m-param a:active, -table.m-table tr.m-param th a:active, -table.m-table th.m-param a:active { - color: #9ad36a; -} -figure.m-figure.m-default::before { - border-color: transparent; -} -figure.m-figure.m-default figcaption { - color: #000000; -} -figure.m-figure.m-primary::before { - border-color: transparent; -} -figure.m-figure.m-primary figcaption { - color: #31708f; -} -figure.m-figure.m-primary figcaption .m-figure-description { - color: #000000; -} -figure.m-figure.m-success::before { - border-color: transparent; -} -figure.m-figure.m-success figcaption { - color: #9ad36a; -} -figure.m-figure.m-success figcaption .m-figure-description { - color: #000000; -} -figure.m-figure.m-warning::before { - border-color: transparent; -} -figure.m-figure.m-warning figcaption { - color: #f9cf79; -} -figure.m-figure.m-warning figcaption .m-figure-description { - color: #000000; -} -figure.m-figure.m-danger::before { - border-color: transparent; -} -figure.m-figure.m-danger figcaption { - color: #f60000; -} -figure.m-figure.m-danger figcaption .m-figure-description { - color: #000000; -} -figure.m-figure.m-info::before { - border-color: transparent; -} -figure.m-figure.m-info figcaption { - color: #31708f; -} -figure.m-figure.m-info figcaption .m-figure-description { - color: #000000; -} -figure.m-figure.m-param::before { - border-color: transparent; -} -figure.m-figure.m-param figcaption { - color: #9ad36a; -} -figure.m-figure.m-dim::before { - border-color: transparent; -} -figure.m-figure.m-dim { - color: #666; -} -figure.m-figure.m-dim a { - color: #949494; -} -figure.m-figure.m-dim a:hover, -figure.m-figure.m-dim a:focus, -figure.m-figure.m-dim a:active { - color: #949494; -} -.m-math { - fill: #000000; -} -.m-math.m-default, -.m-math g.m-default, -.m-math rect.m-default, -div.m-plot svg .m-bar.m-default, -.m-graph g.m-edge polygon, -.m-graph g.m-node:not(.m-flat) ellipse, -.m-graph g.m-node:not(.m-flat) polygon, -.m-graph g.m-edge text, -.m-graph g.m-node.m-flat text, -.m-graph g.m-cluster text, -.m-graph.m-default g.m-edge polygon, -.m-graph.m-default g.m-node:not(.m-flat) ellipse, -.m-graph.m-default g.m-node:not(.m-flat) polygon, -.m-graph.m-default g.m-edge text, -.m-graph.m-default g.m-node.m-flat text, -.m-graph.m-default g.m-cluster text { - fill: #000000; -} -.m-graph g.m-edge polygon, -.m-graph g.m-edge path, -.m-graph g.m-node ellipse, -.m-graph g.m-node polygon, -.m-graph g.m-node polyline, -.m-graph g.m-cluster polygon, -.m-graph.m-default g.m-edge polygon, -.m-graph.m-default g.m-edge path, -.m-graph.m-default g.m-node ellipse, -.m-graph.m-default g.m-node polygon, -.m-graph.m-default g.m-node polyline, -.m-graph.m-default g.m-cluster polygon { - stroke: #000000; -} -.m-math.m-primary, -.m-math g.m-primary, -.m-math rect.m-primary, -div.m-plot svg .m-bar.m-primary, -.m-graph.m-primary g.m-edge polygon, -.m-graph.m-primary g.m-node:not(.m-flat) ellipse, -.m-graph.m-primary g.m-node:not(.m-flat) polygon, -.m-graph.m-primary g.m-edge text, -.m-graph.m-primary g.m-node.m-flat text, -.m-graph.m-primary g.m-cluster text { - fill: #31708f; -} -.m-graph.m-primary g.m-edge polygon, -.m-graph.m-primary g.m-edge path, -.m-graph.m-primary g.m-node ellipse, -.m-graph.m-primary g.m-node polygon, -.m-graph.m-primary g.m-node polyline, -.m-graph.m-primary g.m-cluster polygon { - stroke: #31708f; -} -.m-math.m-success, -.m-math g.m-success, -.m-math rect.m-success, -div.m-plot svg .m-bar.m-success, -.m-graph.m-success g.m-edge polygon, -.m-graph.m-success g.m-node:not(.m-flat) ellipse, -.m-graph.m-success g.m-node:not(.m-flat) polygon, -.m-graph.m-success g.m-edge text, -.m-graph.m-success g.m-node.m-flat text, -.m-graph.m-success g.m-cluster text { - fill: #9ad36a; -} -.m-graph.m-success g.m-edge polygon, -.m-graph.m-success g.m-edge path, -.m-graph.m-success g.m-node ellipse, -.m-graph.m-success g.m-node polygon, -.m-graph.m-success g.m-node polyline, -.m-graph.m-success g.m-cluster polygon { - stroke: #9ad36a; -} -.m-math.m-warning, -.m-math g.m-warning, -.m-math rect.m-warning, -div.m-plot svg .m-bar.m-warning, -.m-graph.m-warning g.m-edge polygon, -.m-graph.m-warning g.m-node:not(.m-flat) ellipse, -.m-graph.m-warning g.m-node:not(.m-flat) polygon, -.m-graph.m-warning g.m-edge text, -.m-graph.m-warning g.m-node.m-flat text, -.m-graph.m-warning g.m-cluster text { - fill: #f9cf79; -} -.m-graph.m-warning g.m-edge polygon, -.m-graph.m-warning g.m-edge path, -.m-graph.m-warning g.m-node ellipse, -.m-graph.m-warning g.m-node polygon, -.m-graph.m-warning g.m-node polyline, -.m-graph.m-warning g.m-cluster polygon { - stroke: #f9cf79; -} -.m-math.m-danger, -.m-math g.m-danger, -.m-math rect.m-danger, -div.m-plot svg .m-bar.m-danger, -.m-graph.m-danger g.m-edge polygon, -.m-graph.m-danger g.m-node:not(.m-flat) ellipse, -.m-graph.m-danger g.m-node:not(.m-flat) polygon, -.m-graph.m-danger g.m-edge text, -.m-graph.m-danger g.m-node.m-flat text, -.m-graph.m-danger g.m-cluster text { - fill: #f60000; -} -.m-graph.m-danger g.m-edge polygon, -.m-graph.m-danger g.m-edge path, -.m-graph.m-danger g.m-node ellipse, -.m-graph.m-danger g.m-node polygon, -.m-graph.m-danger g.m-node polyline, -.m-graph.m-danger g.m-cluster polygon { - stroke: #f60000; -} -.m-math.m-info, -.m-math g.m-info, -.m-math rect.m-info, -div.m-plot svg .m-bar.m-info, -.m-graph.m-info g.m-edge polygon, -.m-graph.m-info g.m-node:not(.m-flat) ellipse, -.m-graph.m-info g.m-node:not(.m-flat) polygon, -.m-graph.m-info g.m-edge text, -.m-graph.m-info g.m-node.m-flat text, -.m-graph.m-info g.m-cluster text { - fill: #31708f; -} -.m-graph.m-info g.m-edge polygon, -.m-graph.m-info g.m-edge path, -.m-graph.m-info g.m-node ellipse, -.m-graph.m-info g.m-node polygon, -.m-graph.m-info g.m-node polyline, -.m-graph.m-info g.m-cluster polygon { - stroke: #31708f; -} -.m-math.m-dim, -.m-math g.m-dim, -.m-math rect.m-dim, -div.m-plot svg .m-bar.m-dim, -.m-graph.m-dim g.m-edge polygon, -.m-graph.m-dim g.m-node:not(.m-flat) ellipse, -.m-graph.m-dim g.m-node:not(.m-flat) polygon, -.m-graph.m-dim g.m-edge text, -.m-graph.m-dim g.m-node.m-flat text, -.m-graph.m-dim g.m-cluster text { - fill: #666; -} -.m-graph.m-dim g.m-edge polygon, -.m-graph.m-dim g.m-edge path, -.m-graph.m-dim g.m-node ellipse, -.m-graph.m-dim g.m-node polygon, -.m-graph.m-dim g.m-node polyline, -.m-graph.m-dim g.m-cluster polygon { - stroke: #666; -} -.m-math.m-param, -.m-math g.m-param, -.m-math rect.m-param, -div.m-plot svg .m-bar.m-param, -.m-graph.m-param g.m-edge polygon, -.m-graph.m-param g.m-node:not(.m-flat) ellipse, -.m-graph.m-param g.m-node:not(.m-flat) polygon, -.m-graph.m-param g.m-edge text, -.m-graph.m-param g.m-node.m-flat text { - fill: #9ad36a; -} -.m-graph.m-param g.m-edge polygon, -.m-graph.m-param g.m-edge path, -.m-graph.m-param g.m-node ellipse, -.m-graph.m-param g.m-node polygon, -.m-graph.m-param g.m-node polyline { - stroke: #9ad36a; -} -.m-graph g.m-edge.m-default polygon, -.m-graph g.m-node.m-default:not(.m-flat) ellipse, -.m-graph g.m-node.m-default:not(.m-flat) polygon, -.m-graph g.m-edge.m-default text, -.m-graph g.m-node.m-default.m-flat text, -.m-graph g.m-cluster.m-default text { - fill: #000000; -} -.m-graph g.m-edge.m-default polygon, -.m-graph g.m-edge.m-default path, -.m-graph g.m-node.m-default ellipse, -.m-graph g.m-node.m-default polygon, -.m-graph g.m-node.m-default polyline, -.m-graph g.m-cluster.m-default polygon { - stroke: #000000; -} -.m-graph g.m-edge.m-primary polygon, -.m-graph g.m-node.m-primary:not(.m-flat) ellipse, -.m-graph g.m-node.m-primary:not(.m-flat) polygon, -.m-graph g.m-edge.m-primary text, -.m-graph g.m-node.m-primary.m-flat text, -.m-graph g.m-cluster.m-primary text { - fill: #31708f; -} -.m-graph g.m-edge.m-primary polygon, -.m-graph g.m-edge.m-primary path, -.m-graph g.m-node.m-primary ellipse, -.m-graph g.m-node.m-primary polygon, -.m-graph g.m-node.m-primary polyline, -.m-graph g.m-cluster.m-primary polygon { - stroke: #31708f; -} -.m-graph g.m-edge.m-success polygon, -.m-graph g.m-node.m-success:not(.m-flat) ellipse, -.m-graph g.m-node.m-success:not(.m-flat) polygon, -.m-graph g.m-edge.m-success text, -.m-graph g.m-node.m-success.m-flat text, -.m-graph g.m-cluster.m-success text { - fill: #9ad36a; -} -.m-graph g.m-edge.m-success polygon, -.m-graph g.m-edge.m-success path, -.m-graph g.m-node.m-success ellipse, -.m-graph g.m-node.m-success polygon, -.m-graph g.m-node.m-success polyline, -.m-graph g.m-cluster.m-success polygon { - stroke: #9ad36a; -} -.m-graph g.m-edge.m-warning polygon, -.m-graph g.m-node.m-warning:not(.m-flat) ellipse, -.m-graph g.m-node.m-warning:not(.m-flat) polygon, -.m-graph g.m-edge.m-warning text, -.m-graph g.m-node.m-warning.m-flat text, -.m-graph g.m-cluster.m-warning text { - fill: #f9cf79; -} -.m-graph g.m-edge.m-warning polygon, -.m-graph g.m-edge.m-warning path, -.m-graph g.m-node.m-warning ellipse, -.m-graph g.m-node.m-warning polygon, -.m-graph g.m-node.m-warning polyline, -.m-graph g.m-cluster.m-warning polygon { - stroke: #f9cf79; -} -.m-graph g.m-edge.m-danger polygon, -.m-graph g.m-node.m-danger:not(.m-flat) ellipse, -.m-graph g.m-node.m-danger:not(.m-flat) polygon, -.m-graph g.m-edge.m-danger text, -.m-graph g.m-node.m-danger.m-flat text, -.m-graph g.m-cluster.m-danger text { - fill: #f60000; -} -.m-graph g.m-edge.m-danger polygon, -.m-graph g.m-edge.m-danger path, -.m-graph g.m-node.m-danger ellipse, -.m-graph g.m-node.m-danger polygon, -.m-graph g.m-node.m-danger polyline, -.m-graph g.m-cluster.m-danger polygon { - stroke: #f60000; -} -.m-graph g.m-edge.m-info polygon, -.m-graph g.m-node.m-info:not(.m-flat) ellipse, -.m-graph g.m-node.m-info:not(.m-flat) polygon, -.m-graph g.m-edge.m-info text, -.m-graph g.m-node.m-info.m-flat text, -.m-graph g.m-cluster.m-info text { - fill: #31708f; -} -.m-graph g.m-edge.m-info polygon, -.m-graph g.m-edge.m-info path, -.m-graph g.m-node.m-info ellipse, -.m-graph g.m-node.m-info polygon, -.m-graph g.m-node.m-info polyline, -.m-graph g.m-cluster.m-info polygon { - stroke: #31708f; -} -.m-graph g.m-edge.m-dim polygon, -.m-graph g.m-node.m-dim:not(.m-flat) ellipse, -.m-graph g.m-node.m-dim:not(.m-flat) polygon, -.m-graph g.m-edge.m-dim text, -.m-graph g.m-node.m-dim.m-flat text, -.m-graph g.m-cluster.m-dim text { - fill: #666; -} -.m-graph g.m-edge.m-dim polygon, -.m-graph g.m-edge.m-dim path, -.m-graph g.m-node.m-dim ellipse, -.m-graph g.m-node.m-dim polygon, -.m-graph g.m-node.m-dim polyline, -.m-graph g.m-cluster.m-dim polygon { - stroke: #666; -} -.m-graph g.m-edge.m-param polygon, -.m-graph g.m-node.m-param:not(.m-flat) ellipse, -.m-graph g.m-node.m-param:not(.m-flat) polygon, -.m-graph g.m-edge.m-param text, -.m-graph g.m-node.m-param.m-flat text { - fill: #9ad36a; -} -.m-graph g.m-edge.m-param polygon, -.m-graph g.m-edge.m-param path, -.m-graph g.m-node.m-param ellipse, -.m-graph g.m-node.m-param polygon, -.m-graph g.m-node.m-param polyline, -.m-graph g.m-cluster.m-param polygon { - stroke: #9ad36a; -} -p, -ul, -ol, -dl, -blockquote, -pre, -.m-code-figure, -.m-console-figure, -hr, -.m-note, -.m-frame, -.m-block, -div.m-button, -div.m-scroll, -table.m-table, -div.m-image, -img.m-image, -svg.m-image, -figure.m-figure, -.m-imagegrid, -div.m-math, -div.m-graph, -div.m-plot { - margin-bottom: 1rem; -} -p:last-child, -p.m-nopadb, -ul:last-child, -ul.m-nopadb, -ol:last-child, -ol.m-nopadb, -dl:last-child, -dl.m-nopadb, -blockquote:last-child, -blockquote.m-nopadb, -pre:last-child, -pre.m-nopadb, -.m-code-figure:last-child, -.m-code-figure.m-nopadb, -.m-console-figure:last-child, -.m-console-figure.m-nopadb, -hr:last-child, -hr.m-nopadb, -.m-note:last-child, -.m-note.m-nopadb, -.m-frame:last-child, -.m-frame.m-nopadb, -.m-block:last-child, -.m-block.m-nopadb, -div.m-button:last-child, -div.m-button.m-nopadb, -div.m-scroll:last-child, -div.m-scroll.m-nopadb, -table.m-table:last-child, -table.m-table.m-nopadb, -img.m-image:last-child, -img.m-image.m-nopadb, -svg.m-image:last-child, -svg.m-image.m-nopadb, -div.m-image:last-child, -div.m-image.m-nopadb, -figure.m-figure:last-child, -figure.m-figure.m-nopadb, -.m-imagegrid:last-child, -.m-imagegrid.m-nopadb, -div.m-math:last-child, -div.m-math.m-nopadb, -div.m-graph:last-child, -div.m-graph.m-nopadb, -div.m-plot:last-child, -div.m-plot.m-nopadb { - margin-bottom: 0; -} -li > p:last-child, -li > blockquote:last-child, -li > pre:last-child, -li > .m-code-figure:last-child, -li > .m-console-figure:last-child, -li > .m-note:last-child, -li > .m-frame:last-child, -li > .m-block:last-child, -li > div.m-button:last-child, -li > div.m-scroll:last-child, -li > table.m-table:last-child, -li > img.m-image:last-child, -li > svg.m-image:last-child, -li > div.m-image:last-child, -li > figure.m-figure:last-child, -li > div.m-math:last-child, -li > div.m-graph:last-child, -li > div.m-plot:last-child { - margin-bottom: 1rem; -} -li:last-child > p:last-child, -li:last-child > p.m-nopadb, -li:last-child > blockquote:last-child, -li:last-child > blockquote.m-nopadb, -li:last-child > pre:last-child, -li:last-child > pre.m-nopadb, -li:last-child > .m-code-figure:last-child, -li:last-child > .m-code-figure.m-nopadb, -li:last-child > .m-console-figure:last-child, -li:last-child > .m-console-figure.m-nopadb, -li:last-child > .m-note:last-child, -li:last-child > .m-note.m-nopadb, -li:last-child > .m-frame:last-child, -li:last-child > .m-frame.m-nopadb, -li:last-child > .m-block:last-child, -li:last-child > .m-block.m-nopadb, -li:last-child > div.m-button:last-child, -li:last-child > div.m-button.m-nopadb, -li:last-child > div.m-scroll:last-child, -li:last-child > div.m-scroll.m-nopadb, -li:last-child > table.m-table:last-child, -li:last-child > table.m-table.m-nopadb, -li:last-child > img.m-image:last-child, -li:last-child > img.m-image.m-nopadb, -li:last-child > svg.m-image:last-child, -li:last-child > svg.m-image.m-nopadb, -li:last-child > div.m-image:last-child, -li:last-child > div.m-image.m-nopadb, -li:last-child > figure.m-figure:last-child, -li:last-child > figure.m-figure.m-nopadb, -li:last-child > div.m-math:last-child, -li:last-child > div.m-math.m-nopadb, -li:last-child > div.m-graph:last-child, -li:last-child > div.m-graph.m-nopadb, -li:last-child > div.m-plot:last-child, -li:last-child > div.m-plot.m-nopadb { - margin-bottom: 0; -} - -body > header > nav { - width: 100%; - background-color: #000000; - min-height: 3rem; - font-size: 16px; -} -body > header > nav.m-navbar-landing, -body > header > nav.m-navbar-cover { - background-color: transparent; - position: relative; -} -body > header > nav.m-navbar-landing { - opacity: 0.8; -} -body > header > nav.m-navbar-cover { - background-color: #000000; - opacity: 1; -} -body > header > nav.m-navbar-landing:hover, -body > header > nav.m-navbar-cover:hover { - background-color: #000000; - opacity: 1; -} -body > header > nav.m-navbar-landing:target, -body > header > nav.m-navbar-cover:target { - background-color: #000000; - opacity: 1; -} -body > header > nav.m-navbar-landing #m-navbar-brand.m-navbar-brand-hidden { - visibility: hidden; -} -body - > header - > nav.m-navbar-landing:target - #m-navbar-brand.m-navbar-brand-hidden { - visibility: visible; -} -body > header > nav { - margin-left: auto; - margin-right: auto; - color: #ffffff; -} -body > header > nav a { - text-decoration: none; - text-transform: none; - display: inline-block; - vertical-align: middle; - line-height: 2.75rem; - color: #ffffff; -} -body > header > nav #m-navbar-brand, -body > header > nav a#m-navbar-show, -body > header > nav a#m-navbar-hide { - font-weight: 300; - font-size: 1.125rem; - padding-left: 1rem; - padding-right: 1rem; -} -body > header > nav a#m-navbar-brand, -body > header > nav #m-navbar-brand a { - text-transform: none; -} -body > header > nav a#m-navbar-brand img, -body > header > nav #m-navbar-brand a img { - height: 5rem; - vertical-align: -22.5%; - margin-right: 0.5rem; -} -body > header > nav #m-navbar-brand a { - padding-left: 0; - padding-right: 0; -} -body > header > nav #m-navbar-brand .m-thin { - font-weight: normal; -} -body > header > nav #m-navbar-brand .m-breadcrumb { - color: #bdbdbd; -} -body > header > nav a#m-navbar-show::before, -body > header > nav a#m-navbar-hide::before { - content: "\2630"; -} -body > header > nav #m-navbar-collapse { - padding-bottom: 1rem; -} -body > header > nav #m-navbar-collapse li { - border-style: solid; - border-color: transparent; - border-width: 0 0 0 0.25rem; - margin-left: -1rem; -} -body > header > nav #m-navbar-collapse li a { - border-style: solid; - border-color: transparent; - line-height: 1.5rem; - margin-left: -0.25rem; - padding-left: 0.75rem; - border-width: 0 1px 1px 1px; - width: 100%; -} -body > header > nav #m-navbar-collapse li ol { - border-color: #ddd; -} -body > header > nav #m-navbar-collapse li a#m-navbar-current { - color: #ffffff; - background-color: #000000; - border-color: #000000; -} -body > header > nav #m-navbar-collapse li ol li a#m-navbar-current { - color: #000000; - background-color: #ffffff; - border-color: #ddd; -} -body > header > nav ol { - list-style-type: none; - margin: 0; -} -body > header > nav ol ol { - padding-left: 1.5rem; -} -body > header > nav .m-row > [class*="m-col-"] { - padding-top: 0; - padding-bottom: 0; -} -body > header > nav a:hover, -body > header > nav a:focus, -body > header > nav a:active { - color: #ffffff; -} -body > header > nav #m-navbar-collapse li:hover { - border-color: #ffffff; -} -body > header > nav #m-navbar-collapse li a:hover, -body > header > nav #m-navbar-collapse li a:focus, -body > header > nav #m-navbar-collapse li a:active { - border-color: #ffffff; - background-color: #000000; -} -body > header > nav.m-navbar-landing #m-navbar-collapse li a:hover, -body > header > nav.m-navbar-cover #m-navbar-collapse li a:hover, -body > header > nav.m-navbar-landing #m-navbar-collapse li a:focus, -body > header > nav.m-navbar-cover #m-navbar-collapse li a:focus, -body > header > nav.m-navbar-landing #m-navbar-collapse li a:active, -body > header > nav.m-navbar-cover #m-navbar-collapse li a:active { - background-color: var(--header-link-active-background-color-semi); -} -body > header > nav #m-navbar-hide { - display: none; -} -body > header > nav:target #m-navbar-collapse { - display: block; -} -body > header > nav:target #m-navbar-show { - display: none; -} -body > header > nav:target #m-navbar-hide { - display: inline-block; -} -@media screen and (min-width: 768px) { - body > header > nav #m-navbar-show, - body > header > nav #m-navbar-hide, - body > header > nav:target #m-navbar-show, - body > header > nav:target #m-navbar-hide { - display: none; - } - body > header > nav #m-navbar-collapse li a { - line-height: 2.75rem; - } - body > header > nav a, - body > header > nav #m-navbar-collapse li a { - margin-left: 0; - padding-left: 1rem; - padding-right: 1rem; - white-space: nowrap; - } - body > header > nav #m-navbar-collapse { - padding-bottom: 0; - } - body > header > nav #m-navbar-collapse li ol { - background-color: #000000; - } - body > header > nav #m-navbar-collapse ol ol li { - margin-left: 0; - padding-left: 0; - border-left-width: 0; - } - body > header > nav #m-navbar-collapse ol ol li a { - padding-left: 0.75rem; - color: #000000; - background-color: #ffffff; - border-color: #ddd; - } - body > header > nav #m-navbar-collapse ol ol li a:active { - padding-left: 0.75rem; - color: #ffffff; - background-color: #353535; - border-color: #ddd; - } - body > header > nav #m-navbar-collapse ol ol li a:hover { - padding-left: 0.75rem; - color: #ffffff; - background-color: #353535; - border-color: #ddd; - } - body > header > nav #m-navbar-collapse > .m-row > ol > li { - margin-left: 0; - border-left-width: 0; - } - body > header > nav #m-navbar-collapse > .m-row > ol > li > a { - border-width: 0.25rem 0 0 0; - } - body > header > nav #m-navbar-collapse ol { - padding-left: 0; - padding-right: 0; - } - body > header > nav #m-navbar-collapse > .m-row > ol, - body > header > nav #m-navbar-collapse > .m-row > ol > li { - float: left; - } - body > header > nav #m-navbar-collapse ol ol { - z-index: 99999; - position: absolute; - visibility: hidden; - } - body > header > nav #m-navbar-collapse li:hover ol { - visibility: visible; - } -} -body > footer { - width: 100%; -} -body > footer > nav { - padding-top: 1rem; - padding-bottom: 1rem; - font-size: 0.85rem; - text-align: center; - color: #777777; - background-color: #353535; -} -body > footer > nav h3, -body > footer > nav h3 a { - text-transform: capitalize; - font-weight: normal; -} -body > footer > nav ul { - list-style-type: none; - padding: 0; - margin: 0; -} -body > footer > nav a { - text-decoration: none; - text-transform: none; - color: #999; -} -body > footer > nav a:hover, -body > footer > nav a:focus, -body > footer > nav a:active { - color: #494949; -} -body > main { - padding-top: 1rem; - padding-bottom: 1rem; -} -article h1 { - font-size: 1.75rem; -} -article h1 .m-breadcrumb { - color: #666; - font-weight: normal; - font-size: 16px; - padding-top: 8px; - padding-bottom: 8px; -} -article h1 .m-breadcrumb a { - color: #26a9e0; -} -article h1 .m-breadcrumb a:hover, -article h1 a:focus, -article h1 a:active { - color: #26a9e0; -} -article hr { - width: 75%; - border-width: 2px 0 0 0; - border-style: solid; - border-color: #92d050; - margin: auto; -} -article section hr { - width: 50%; - border-width: 1px 0 0 0; - border-style: solid; - border-color: #ddd; - margin: auto; - padding-top: 5px; - padding-bottom: 10px; -} -article > header h1 { - font-size: 2rem; - margin-bottom: 0.5rem; -} -article h1 a, -article > header h1, -article > header h1 a, -article section > h2, -article section > h2 a, -article section > h3, -article section > h3 a, -article section > h4, -article section > h4 a, -article section > h5, -article section > h5 a, -article section > h6, -article section > h6 a { - color: #000000; -} -article h1 a:hover, -article > header h1 a:hover, -article > header h1 a:focus, -article > header h1 a:active, -article section > h2 a:hover, -article section > h2 a:focus, -article section > h2 a:active, -article section > h3 a:hover, -article section > h3 a:focus, -article section > h3 a:active, -article section > h4 a:hover, -article section > h4 a:focus, -article section > h4 a:active, -article section > h5 a:hover, -article section > h5 a:focus, -article section > h5 a:active, -article section > h6 a:hover, -article section > h6 a:focus, -article section > h6 a:active { - color: #000000; -} -article > header .m-date { - display: block; - width: 2.5rem; - float: left; - text-align: center; - line-height: 95%; - font-size: 0.75rem; - font-weight: normal; - white-space: nowrap; - border-right-style: solid; - border-right-width: 0.125rem; - border-color: #000000; - padding-right: 0.75rem; - margin-top: -0.1rem; - margin-right: 0.75rem; - margin-bottom: 0.25rem; -} -article > header .m-date-day { - display: block; - font-weight: bold; - padding-top: 0.2rem; - padding-bottom: 0.15rem; - font-size: 1.25rem; -} -article > header p { - color: #7a7a7a; - font-size: 1.125rem; -} -article > header h1::after { - content: " "; - clear: both; - display: table; -} -article > footer { - color: #969696; -} -article > footer p { - font-style: italic; - font-size: 0.85rem; - text-indent: 0; -} -article h1 a, -article > header h1 a, -article section > h2 a, -article section > h3 a, -article section > h4 a, -article section > h5 a, -article section > h6 a { - text-decoration: none; -} -#m-landing-image, -#m-cover-image, -article#m-jumbo > header #m-jumbo-image { - background-size: cover; - background-color: #666666; - background-position: center center; - background-repeat: no-repeat; - margin-top: -4rem; - padding-top: 5rem; -} -#m-landing-image { - color: #ffffff; -} -#m-cover-image { - height: 30rem; - margin-bottom: -26rem; -} -#m-landing-cover h1 { - font-size: 2.8rem; - margin-top: -0.5rem; - padding-left: 1.5rem; - padding-bottom: 1rem; - text-transform: capitalize; -} -#m-landing-cover { - padding-bottom: 10rem; - margin-bottom: -6rem; -} -article#m-jumbo { - margin-top: -1rem; -} -#m-landing-cover, -#m-cover-image > div, -article#m-jumbo > header #m-jumbo-cover { - background: linear-gradient( - transparent 0%, - transparent 50%, - #e8e8e8 100% - ); - width: 100%; - height: 100%; -} -article#m-jumbo > header h1, -article#m-jumbo > header h2 { - text-align: center; - font-weight: bold; -} -article#m-jumbo > header a { - text-decoration: none; -} -article#m-jumbo > header #m-jumbo-cover { - padding-bottom: 5rem; -} -article#m-jumbo > header #m-jumbo-image { - font-size: 2.5vmin; - margin-bottom: -3rem; -} -article#m-jumbo > header h1 { - font-size: 10vmin; -} -article#m-jumbo > header h2 { - font-size: 3vmin; -} -@media screen and (max-height: 640px), screen and (max-width: 640px) { - article#m-jumbo > header h1 { - font-size: 3rem; - } - article#m-jumbo > header #m-jumbo-image, - article#m-jumbo > header h2 { - font-size: 1rem; - } -} -article#m-jumbo > header, -article#m-jumbo > header h1, -article#m-jumbo > header a { - color: #ffffff; -} -article#m-jumbo > header a:hover, -article#m-jumbo > header a:focus, -article#m-jumbo > header a:active { - color: #f0f0f0; -} -article#m-jumbo.m-inverted > header, -article#m-jumbo.m-inverted > header h1, -article#m-jumbo.m-inverted > header a { - color: #000000; -} -article#m-jumbo.m-inverted > header a:hover, -article#m-jumbo.m-inverted > header a:focus, -article#m-jumbo.m-inverted > header a:active { - color: #0f0f0f; -} -.m-landing-news h3 a { - color: #000000; - text-decoration: none; - text-transform: capitalize; -} -.m-landing-news h3 a:hover, -.m-landing-news h3 a:hover, -.m-landing-news h3 a:focus, -.m-landing-news h3 a:active { - color: #000000; -} -.m-landing-news time { - display: inline-block; - margin-left: 1rem; - float: right; -} -.m-article-pagination { - text-align: center; - padding: 1rem; -} -nav.m-navpanel { - text-align: center; -} -nav.m-navpanel h3 { - text-transform: capitalize; - font-weight: normal; -} -nav.m-navpanel ol { - text-transform: capitalize; -} -nav.m-navpanel ol, -nav.m-navpanel ul { - list-style-type: none; - padding: 0; -} -nav.m-navpanel a { - color: #292929; - text-decoration: none; -} -nav.m-navpanel a:hover, -nav.m-navpanel a:focus, -nav.m-navpanel a:active { - color: #cb4b16; -} -ul.m-tagcloud li { - display: inline; -} -ul.m-tagcloud li.m-tag-1 { - font-size: 0.75rem; -} -ul.m-tagcloud li.m-tag-2 { - font-size: 0.825rem; -} -ul.m-tagcloud li.m-tag-3 { - font-size: 1rem; -} -ul.m-tagcloud li.m-tag-4 { - font-size: 1.25rem; -} -ul.m-tagcloud li.m-tag-5 { - font-size: 1.5rem; -} -article section:target figure.m-code-figure, -article section:target figure.m-console-figure { - z-index: 1; -} -article, -article > header, -article section { - margin-bottom: 1rem; -} -article:last-child, -article section:last-child { - margin-bottom: 0; -} -.m-container-inflatable section:target > .m-note, -.m-container-inflatable section:target > .m-frame, -.m-container-inflatable section:target > .m-block, -.m-container-inflatable section:target > pre, -.m-container-inflatable section:target > .m-code-figure > pre:first-child, -.m-container-inflatable section:target > .m-console-figure > pre:first-child, -.m-container-inflatable section:target section > .m-note, -.m-container-inflatable section:target section > .m-frame, -.m-container-inflatable section:target section > .m-block, -.m-container-inflatable section:target section > pre, -.m-container-inflatable - section:target - section - > .m-code-figure - > pre:first-child, -.m-container-inflatable - section:target - section - > .m-console-figure - > pre:first-child, -.m-container-inflatable section:target [class*="m-center-"] > .m-note, -.m-container-inflatable section:target [class*="m-center-"] > .m-frame, -.m-container-inflatable section:target [class*="m-center-"] > .m-block, -.m-container-inflatable section:target [class*="m-center-"] > pre, -.m-container-inflatable - section:target - [class*="m-center-"] - > .m-code-figure - > pre:first-child, -.m-container-inflatable - section:target - [class*="m-center-"] - > .m-console-figure - > pre:first-child, -.m-container-inflatable section:target [class*="m-left-"] > .m-note, -.m-container-inflatable section:target [class*="m-left-"] > .m-frame, -.m-container-inflatable section:target [class*="m-left-"] > .m-block, -.m-container-inflatable section:target [class*="m-left-"] > pre, -.m-container-inflatable - section:target - [class*="m-left-"] - > .m-code-figure - > pre:first-child, -.m-container-inflatable - section:target - [class*="m-left-"] - > .m-console-figure - > pre:first-child, -.m-container-inflatable section:target [class*="m-right-"] > .m-note, -.m-container-inflatable section:target [class*="m-right-"] > .m-frame, -.m-container-inflatable section:target [class*="m-right-"] > .m-block, -.m-container-inflatable section:target [class*="m-right-"] > pre, -.m-container-inflatable - section:target - [class*="m-right-"] - > .m-code-figure - > pre:first-child, -.m-container-inflatable - section:target - [class*="m-right-"] - > .m-console-figure - > pre:first-child, -.m-container-inflatable section:target .m-container-inflate > .m-note, -.m-container-inflatable section:target .m-container-inflate > .m-frame, -.m-container-inflatable section:target .m-container-inflate > .m-block, -.m-container-inflatable section:target .m-container-inflate > pre, -.m-container-inflatable - section:target - .m-container-inflate - > .m-code-figure - > pre:first-child, -.m-container-inflatable - section:target - .m-container-inflate - > .m-console-figure - > pre:first-child { - margin-left: -1rem; - border-left-style: solid; - border-left-width: 0.25rem; - border-top-left-radius: 0; - border-bottom-left-radius: 0; - padding-left: 0.75rem; -} -.m-container-inflatable section:target > .m-code-figure::before, -.m-container-inflatable section:target > .m-console-figure::before, -.m-container-inflatable section:target section > .m-code-figure::before, -.m-container-inflatable section:target section > .m-console-figure::before, -.m-container-inflatable - section:target - [class*="m-center-"] - > .m-code-figure::before, -.m-container-inflatable - section:target - [class*="m-center-"] - > .m-console-figure::before, -.m-container-inflatable - section:target - [class*="m-left-"] - > .m-code-figure::before, -.m-container-inflatable - section:target - [class*="m-left-"] - > .m-console-figure::before, -.m-container-inflatable - section:target - [class*="m-right-"] - > .m-code-figure::before, -.m-container-inflatable - section:target - [class*="m-right-"] - > .m-console-figure::before, -.m-container-inflatable - section:target - .m-container-inflate - > .m-code-figure::before, -.m-container-inflatable - section:target - .m-container-inflate - > .m-console-figure::before { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - border-left-width: 0.25rem; -} -.m-container-inflatable section:target > .m-code-figure > pre.m-nopad, -.m-container-inflatable section:target > .m-console-figure > pre.m-nopad { - margin-left: -0.75rem; - padding-left: -0.75rem; -} -@media screen and (min-width: 576px) { - .m-container-inflatable section:target .m-center-s > .m-note, - .m-container-inflatable section:target .m-center-s > pre, - .m-container-inflatable - section:target - .m-center-s - > figure.m-code-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-center-s - > figure.m-console-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-right-s - > figure.m-code-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-right-s - > figure.m-console-figure - > pre:first-child { - border-left-width: 0; - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - padding-left: 1rem; - } - .m-container-inflatable section:target .m-center-s > .m-block, - .m-container-inflatable section:target .m-right-s > .m-block { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - } - .m-container-inflatable section:target .m-center-s > .m-frame, - .m-container-inflatable section:target .m-right-s > .m-frame { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - border-left-width: 0.125rem; - padding-left: 0.875rem; - } - .m-container-inflatable section:target .m-right-s > .m-block, - .m-container-inflatable section:target .m-right-s > .m-frame { - margin-left: 0; - } - .m-container-inflatable section:target .m-right-s > .m-note, - .m-container-inflatable section:target .m-right-s > pre { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - margin-left: 0; - border-left-width: 0; - padding-left: 1rem; - } - .m-container-inflatable - section:target - .m-center-s - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-center-s - > figure.m-console-figure::before, - .m-container-inflatable - section:target - .m-right-s - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-right-s - > figure.m-console-figure::before { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - border-left-width: 0.125rem; - } -} -@media screen and (min-width: 768px) { - .m-container-inflatable section:target .m-center-m > .m-note, - .m-container-inflatable section:target .m-center-m > pre, - .m-container-inflatable - section:target - .m-center-m - > figure.m-code-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-center-m - > figure.m-console-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-right-m - > figure.m-code-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-right-m - > figure.m-console-figure - > pre:first-child { - border-left-width: 0; - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - padding-left: 1rem; - } - .m-container-inflatable section:target .m-center-m > .m-block, - .m-container-inflatable section:target .m-right-m > .m-block { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - } - .m-container-inflatable section:target .m-center-m > .m-frame, - .m-container-inflatable section:target .m-right-m > .m-frame { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - border-left-width: 0.125rem; - padding-left: 0.875rem; - } - .m-container-inflatable section:target .m-right-m > .m-block, - .m-container-inflatable section:target .m-right-m > .m-frame { - margin-left: 0; - } - .m-container-inflatable section:target .m-right-m > .m-note, - .m-container-inflatable section:target .m-right-m > pre { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - margin-left: 0; - border-left-width: 0; - padding-left: 1rem; - } - .m-container-inflatable - section:target - .m-center-m - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-center-m - > figure.m-console-figure::before, - .m-container-inflatable - section:target - .m-right-m - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-right-m - > figure.m-console-figure::before { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - border-left-width: 0.125rem; - } -} -@media screen and (min-width: 992px) { - .m-container-inflatable section:target .m-center-l > .m-note, - .m-container-inflatable section:target .m-center-l > pre, - .m-container-inflatable - section:target - .m-center-l - > figure.m-code-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-center-l - > figure.m-console-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-right-l - > figure.m-code-figure - > pre:first-child, - .m-container-inflatable - section:target - .m-right-l - > figure.m-console-figure - > pre:first-child { - border-left-width: 0; - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - padding-left: 1rem; - } - .m-container-inflatable section:target .m-center-l > .m-block, - .m-container-inflatable section:target .m-right-l > .m-block { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - } - .m-container-inflatable section:target .m-center-l > .m-frame, - .m-container-inflatable section:target .m-right-l > .m-frame { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - border-left-width: 0.125rem; - padding-left: 0.875rem; - } - .m-container-inflatable section:target .m-right-l > .m-block, - .m-container-inflatable section:target .m-right-l > .m-frame { - margin-left: 0; - } - .m-container-inflatable section:target .m-right-l > .m-note, - .m-container-inflatable section:target .m-right-l > pre { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - margin-left: 0; - border-left-width: 0; - padding-left: 1rem; - } - .m-container-inflatable - section:target - .m-center-l - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-center-l - > figure.m-console-figure::before, - .m-container-inflatable - section:target - .m-right-l - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-right-l - > figure.m-console-figure::before { - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - border-left-width: 0.125rem; - } -} -.m-container-inflatable section:target > figure.m-code-figure::before, -.m-container-inflatable section:target > figure.m-console-figure::before, -.m-container-inflatable section:target section > figure.m-code-figure::before, -.m-container-inflatable - section:target - section - > figure.m-console-figure::before, -.m-container-inflatable - section:target - [class*="m-center-"] - > figure.m-code-figure::before, -.m-container-inflatable - section:target - [class*="m-center-"] - > figure.m-console-figure::before, -.m-container-inflatable - section:target - [class*="m-left-"] - > figure.m-code-figure::before, -.m-container-inflatable - section:target - [class*="m-left-"] - > figure.m-console-figure::before, -.m-container-inflatable - section:target - [class*="m-right-"] - > figure.m-code-figure::before, -.m-container-inflatable - section:target - [class*="m-right-"] - > figure.m-console-figure::before, -.m-container-inflatable - section:target - .m-container-inflatable - > figure.m-code-figure::before, -.m-container-inflatable - section:target - .m-container-inflatable - > figure.m-console-figure::before { - border-left-color: #ddd; -} -@media screen and (min-width: 576px) { - .m-container-inflatable - section:target - .m-center-s - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-right-s - > figure.m-code-figure::before { - border-color: #f7f7f7; - } - .m-container-inflatable - section:target - .m-center-s - > figure.m-console-figure::before, - .m-container-inflatable - section:target - .m-right-s - > figure.m-console-figure::before { - border-color: #f7f7f7; - } -} -@media screen and (min-width: 768px) { - .m-container-inflatable - section:target - .m-center-m - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-right-m - > figure.m-code-figure::before { - border-color: #f7f7f7; - } - .m-container-inflatable - section:target - .m-center-m - > figure.m-console-figure::before, - .m-container-inflatable - section:target - .m-right-m - > figure.m-console-figure::before { - border-color: #f7f7f7; - } -} -@media screen and (min-width: 992px) { - .m-container-inflatable - section:target - .m-center-l - > figure.m-code-figure::before, - .m-container-inflatable - section:target - .m-right-l - > figure.m-code-figure::before { - border-color: #f7f7f7; - } - .m-container-inflatable - section:target - .m-center-l - > figure.m-console-figure::before, - .m-container-inflatable - section:target - .m-right-l - > figure.m-console-figure::before { - border-color: #f7f7f7; - } -} -.m-container-inflatable section:target pre, -.m-container-inflatable section:target figure.m-code-figure > pre:first-child, -.m-container-inflatable - section:target - figure.m-console-figure - > pre:first-child { - border-color: #ddd; -} -.m-container-inflatable section:target .m-note.m-default { - border-color: #ddd; -} -.m-container-inflatable section:target .m-note.m-primary { - border-color: #31708f; -} -.m-container-inflatable section:target .m-note.m-success { - border-color: #9ad36a; -} -.m-container-inflatable section:target .m-note.m-warning { - border-color: #f9cf79; -} -.m-container-inflatable section:target .m-note.m-danger { - border-color: #f60000; -} -.m-container-inflatable section:target .m-note.m-info { - border-color: #31708f; -} -.m-container-inflatable section:target .m-note.m-dim { - border-color: #666; -} - -.m-code .c { - color: #95a5a6; -} -.m-code .err { - color: #a61717; -} -.m-code .k { - color: #728e00; -} -.m-code .n { - color: #434f54; -} -.m-code .o { - color: #728e00; -} -.m-code .ch { - color: #95a5a6; -} -.m-code .cm { - color: #95a5a6; -} -.m-code .cp { - color: #728e00; -} -.m-code .cpf { - color: #95a5a6; -} -.m-code .c1 { - color: #95a5a6; -} -.m-code .cs { - color: #95a5a6; -} -.m-code .kc { - color: #00979d; -} -.m-code .kd { - color: #728e00; -} -.m-code .kn { - color: #728e00; -} -.m-code .kp { - color: #00979d; -} -.m-code .kr { - color: #00979d; -} -.m-code .kt { - color: #00979d; -} -.m-code .m { - color: #8a7b52; -} -.m-code .s { - color: #7f8c8d; -} -.m-code .na { - color: #434f54; -} -.m-code .nb { - color: #728e00; -} -.m-code .nc { - color: #434f54; -} -.m-code .no { - color: #434f54; -} -.m-code .nd { - color: #434f54; -} -.m-code .ni { - color: #434f54; -} -.m-code .ne { - color: #434f54; -} -.m-code .nf { - color: #d35400; -} -.m-code .nl { - color: #434f54; -} -.m-code .nn { - color: #434f54; -} -.m-code .nx { - color: #728e00; -} -.m-code .py { - color: #434f54; -} -.m-code .nt { - color: #434f54; -} -.m-code .nv { - color: #434f54; -} -.m-code .ow { - color: #728e00; -} -.m-code .mb { - color: #8a7b52; -} -.m-code .mf { - color: #8a7b52; -} -.m-code .mh { - color: #8a7b52; -} -.m-code .mi { - color: #8a7b52; -} -.m-code .mo { - color: #8a7b52; -} -.m-code .sa { - color: #7f8c8d; -} -.m-code .sb { - color: #7f8c8d; -} -.m-code .sc { - color: #7f8c8d; -} -.m-code .dl { - color: #7f8c8d; -} -.m-code .sd { - color: #7f8c8d; -} -.m-code .s2 { - color: #7f8c8d; -} -.m-code .se { - color: #7f8c8d; -} -.m-code .sh { - color: #7f8c8d; -} -.m-code .si { - color: #7f8c8d; -} -.m-code .sx { - color: #7f8c8d; -} -.m-code .sr { - color: #7f8c8d; -} -.m-code .s1 { - color: #7f8c8d; -} -.m-code .ss { - color: #7f8c8d; -} -.m-code .bp { - color: #728e00; -} -.m-code .fm { - color: #d35400; -} -.m-code .vc { - color: #434f54; -} -.m-code .vg { - color: #434f54; -} -.m-code .vi { - color: #434f54; -} -.m-code .vm { - color: #434f54; -} -.m-code .il { - color: #8a7b52; -} - -.m-console .hll { background-color: #ffffcc } -.m-console .g-AnsiBackgroundBlack { background-color: #232627 } -.m-console .g-AnsiBackgroundBlue { background-color: #1d99f3 } -.m-console .g-AnsiBackgroundBrightBlack { background-color: #7f8c8d } -.m-console .g-AnsiBackgroundBrightBlue { background-color: #3daee9 } -.m-console .g-AnsiBackgroundBrightCyan { background-color: #16a085 } -.m-console .g-AnsiBackgroundBrightGreen { background-color: #1cdc9a } -.m-console .g-AnsiBackgroundBrightMagenta { background-color: #8e44ad } -.m-console .g-AnsiBackgroundBrightRed { background-color: #c0392b } -.m-console .g-AnsiBackgroundBrightWhite { background-color: #ffffff } -.m-console .g-AnsiBackgroundBrightYellow { background-color: #fdbc4b } -.m-console .g-AnsiBackgroundCyan { background-color: #1abc9c } -.m-console .g-AnsiBackgroundDefault { background-color: #fcfcfc } -.m-console .g-AnsiBackgroundGreen { background-color: #11d116 } -.m-console .g-AnsiBackgroundMagenta { background-color: #9b59b6 } -.m-console .g-AnsiBackgroundRed { background-color: #ed1515 } -.m-console .g-AnsiBackgroundWhite { background-color: #fcfcfc } -.m-console .g-AnsiBackgroundYellow { background-color: #f67400 } -.m-console .g-AnsiBlack { color: #232627 } -.m-console .g-AnsiBlue { color: #1d99f3 } -.m-console .g-AnsiBrightBlack { color: #7f8c8d; font-weight: bold } -.m-console .g-AnsiBrightBlue { color: #3daee9; font-weight: bold } -.m-console .g-AnsiBrightCyan { color: #16a085; font-weight: bold } -.m-console .g-AnsiBrightDefault { color: #ffffff; font-weight: bold } -.m-console .g-AnsiBrightGreen { color: #1cdc9a; font-weight: bold } -.m-console .g-AnsiBrightMagenta { color: #8e44ad; font-weight: bold } -.m-console .g-AnsiBrightRed { color: #c0392b; font-weight: bold } -.m-console .g-AnsiBrightWhite { color: #ffffff; font-weight: bold } -.m-console .g-AnsiBrightYellow { color: #fdbc4b; font-weight: bold } -.m-console .g-AnsiCyan { color: #1abc9c } -.m-console .g-AnsiDefault { color: #fcfcfc } -.m-console .g-AnsiGreen { color: #11d116 } -.m-console .g-AnsiMagenta { color: #9b59b6 } -.m-console .g-AnsiRed { color: #ed1515 } -.m-console .g-AnsiWhite { color: #fcfcfc } -.m-console .g-AnsiYellow { color: #f67400 } -.m-console .go { color: #fcfcfc } -.m-console .gp { color: #16a085; font-weight: bold } -.m-console .w { color: #fcfcfc } - -a.m-doc, -a.m-doc-self, -a.m-doc-external, -ul.m-doc li.m-doc-expansible > a:first-child, -ul.m-doc li.m-doc-collapsible > a:first-child, -.m-code.m-inverted.m-doc-include > a { - text-decoration: none; -} -a.m-doc, -a.m-doc-self { - font-weight: bold; -} -.m-thin a.m-doc, -.m-thin a.m-doc-self { - font-weight: normal; -} -ul.m-doc li.m-doc-expansible > a:first-child, -ul.m-doc li.m-doc-collapsible > a:first-child, -ul.m-doc li.m-doc-expansible > a:first-child:hover, -ul.m-doc li.m-doc-expansible > a:first-child:focus, -ul.m-doc li.m-doc-expansible > a:first-child:active, -ul.m-doc li.m-doc-collapsible > a:first-child:hover, -ul.m-doc li.m-doc-collapsible > a:first-child:focus, -ul.m-doc li.m-doc-collapsible > a:first-child:active { - color: #000000; -} -a.m-doc-self, -ul.m-doc li.m-doc-expansible > a:first-child::before, -ul.m-doc li.m-doc-collapsible > a:first-child::before { - color: #26a9e0; -} -a.m-doc-self:hover, -a.m-doc-self:focus, -a.m-doc-self:active, -ul.m-doc li.m-doc-expansible > a:first-child:hover::before, -ul.m-doc li.m-doc-expansible > a:first-child:focus::before, -ul.m-doc li.m-doc-expansible > a:first-child:active::before, -ul.m-doc li.m-doc-collapsible > a:first-child:hover::before, -ul.m-doc li.m-doc-collapsible > a:first-child:focus::before, -ul.m-doc li.m-doc-collapsible > a:first-child:active::before { - color: #26a9e0; -} -h3 a.m-doc-external { - font-weight: normal; -} -span.m-doc-wrap-bumper { - margin-right: -1rem; - display: inline-block; - vertical-align: text-top; -} -span.m-doc-wrap { - padding-left: 1rem; - display: inline-block; - vertical-align: text-top; - white-space: pre-line; - max-width: 100%; -} -dl.m-doc dd { - margin-bottom: 0.5rem; -} -dl.m-doc dd { - margin-left: 0; - padding-left: 2.5rem; -} -ul.m-doc { - list-style: none; - margin-left: 1.0375rem; - padding-left: 0.9rem; - border-left-color: #ddd; - border-left-width: 0.0625rem; - border-left-style: solid; -} -ul.m-doc li { - text-indent: -1rem; - padding-left: 1rem; -} -ul.m-doc li.m-doc-expansible > ul { - display: none; -} -ul.m-doc li.m-doc-expansible, -ul.m-doc li.m-doc-collapsible { - padding-left: 0.6rem; -} -ul.m-doc li.m-doc-expansible > ul.m-doc, -ul.m-doc li.m-doc-collapsible > ul.m-doc { - margin-left: 0.5rem; -} -ul.m-doc li.m-doc-expansible > a:first-child::before, -ul.m-doc li.m-doc-collapsible > a:first-child::before { - background-color: #e8e8e8; - display: inline-block; - width: 0.4rem; - font-weight: bold; -} -ul.m-doc li.m-doc-expansible > a:first-child::before { - content: '+'; -} -ul.m-doc li.m-doc-collapsible > a:first-child::before { - content: '-'; -} -h1 .m-doc-template, -h1 .m-doc-include { - font-size: 1.3rem; - font-weight: normal; - float: right; -} -h1 .m-doc-include:last-child { - margin-bottom: -0.5rem; -} -h3 .m-doc-template, -h3 .m-doc-include { - font-size: 1rem; - font-weight: normal; -} -.m-doc-template, -dl.m-doc dd, -ul.m-doc li > span.m-doc { - color: #666; -} -dl.m-doc dd svg.m-math, -ul.m-doc li > span.m-doc svg.m-math { - fill: #666; -} -.m-doc-template a, -dl.m-doc dd a, -ul.m-doc li > span.m-doc a { - color: #949494; -} -.m-doc-template a:hover, -.m-doc-template a:focus, -.m-doc-template a:active, -dl.m-doc dd a:hover, -dl.m-doc dd a:focus, -dl.m-doc dd a:active, -ul.m-doc li > span.m-doc a:hover, -ul.m-doc li > span.m-doc a:focus, -ul.m-doc li > span.m-doc a:active { - color: #949494; -} -.m-code.m-inverted.m-doc-include > a:link, -.m-code.m-inverted.m-doc-include > a:visited { - opacity: 0.6666; -} -.m-code.m-inverted.m-doc-include > a:hover, -.m-code.m-inverted.m-doc-include > a:focus, -.m-code.m-inverted.m-doc-include > a:active { - opacity: 1; -} -article section.m-doc-details > div { - margin-top: 0; - margin-left: 0; - margin-right: 0; - position: relative; - padding: 1rem; -} -article section.m-doc-details > div::before { - position: absolute; - content: ' '; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: -1; - border-style: solid; - border-width: 0.125rem; - border-radius: 0px; - border-color: #f7f7f7; -} -article section.m-doc-details > div > h3:first-child { - position: relative; - margin: -1rem -1rem 1rem -1rem; - padding: 0.5rem 1rem; - background-color: #ffffff; - border-top-left-radius: 0px; - border-top-right-radius: 0px; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - border-style: solid; - border-width: 2px; - border-color: rgba(91, 91, 91, 0.33); -} -article section.m-doc-details:target { - border-color: transparent; -} -article section.m-doc-details:target > div { - z-index: 1; -} -.m-container-inflatable > .m-row > [class*='m-col-'] section.m-doc-details > div { - margin-left: -1rem; - margin-right: -1rem; -} -#m-search-button { - color: #fff; - margin-left: 30px; - cursor: pointer; - font-size: 18px; - line-height: 1; - padding: 30.5px 0; -} -#m-search-button:before { - font-family: 'FontAwesome'; - content: '\f002'; -} -a.m-doc-search-icon { - padding-left: 1rem; - padding-right: 1rem; -} -a.m-doc-search-icon svg { - fill: #ffffff; -} -body > header > nav #m-navbar-collapse a.m-doc-search-icon svg { - vertical-align: -5%; -} -a.m-doc-search-icon:focus svg, -a.m-doc-search-icon:hover svg, -a.m-doc-search-icon:active svg { - fill: #ffffff; -} -.m-doc-search { - display: none; - z-index: 10; - position: fixed; - left: 0; - right: 0; - top: 110px; - bottom: 0; - background-color: #e8e8e8; -} -.m-doc-search:target { - display: block; -} -.m-doc-search > a { - display: block; - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; -} -.m-doc-search-header { - margin-top: 2.5rem; - padding: 0.5rem 1rem; - height: 2rem; -} -.m-doc-search-header > div:first-child { - float: right; -} -.m-doc-search-content { - background-color: #ffffff; - border-radius: 0px; - padding: 1rem; -} -.m-doc-search input { - width: 100%; - height: 3rem; - font-size: 1.2rem; - border-width: 0; - color: #000000; - background-color: #e8e8e8; - border-radius: 0px; - margin-bottom: 1rem; - padding: 0 1rem; -} -.m-doc-search #search-notfound { - display: none; -} -.m-doc-search ul#search-results { - list-style-type: none; - padding-left: 0; - max-height: calc(100vh - 12.5rem); - overflow-y: auto; - display: none; -} -.m-doc-search ul#search-results li a { - display: block; - padding-left: 1rem; - padding-right: 1rem; - text-decoration: none; - width: 100%; - line-height: 1.5rem; - color: #000000; -} -.m-doc-search ul#search-results li a > div { - white-space: nowrap; - overflow: hidden; -} -.m-doc-search ul#search-results li a > div:not(.m-doc-search-alias) { - direction: rtl; -} -.m-doc-search ul#search-results li a .m-label { - float: right; - line-height: 1rem; - margin-top: 0.1rem; - margin-left: 0.25rem; -} -.m-doc-search ul#search-results li a .m-label.m-flat { - margin-right: -0.75rem; -} -.m-doc-search ul#search-results li#search-current a { - background-color: transparent; -} -.m-doc-search ul#search-results li#search-current.m-doc-search-copied a { - background-color: transparent; -} -.m-doc-search-typed { - color: #26a9e0; -} -.m-doc-search input[type='search'] { - -webkit-appearance: textfield; -} -.m-doc-search input[type='search']::-webkit-search-decoration, -.m-doc-search input[type='search']::-webkit-search-cancel-button, -.m-doc-search input[type='search']::-webkit-search-results-button, -.m-doc-search input[type='search']::-webkit-search-results-decoration { - display: none; -} diff --git a/docs/markdown_prefilter.py b/docs/markdown_prefilter.py deleted file mode 100644 index 2ab05e26f..000000000 --- a/docs/markdown_prefilter.py +++ /dev/null @@ -1,355 +0,0 @@ -#!/usr/bin/env python -#%% -import enum -import fileinput -import re -import sys -import string - -# a helper function to go from snake back to camel -def snake_to_camel(snake_str): - components = snake_str.strip().split("_") - # We capitalize the first letter of each component except the first one - # with the 'title' method and join them together. - camel_str = components[0] + "".join(x.title() for x in components[1:]) - if camel_str.startswith("_"): - return camel_str[1:] - else: - return camel_str - - -def camel_to_snake(name): - name = name.strip().replace(" ", "_") - name = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name.strip()) - return re.sub("([a-z0-9])([A-Z])", r"\1_\2", name).lower() - - -def github_slugify(name): - return ( - name.strip() - .lower() - .replace( - "-", " " - ) # convert dashes to spaces so they don't get lost with other punctuation - .translate(str.maketrans("", "", string.punctuation)) - .replace(" ", " ") - .replace(" ", " ") - .replace(" ", "-") - ) - - -# Add a start comment to make the entire markdown file function as a comment block -# Without this doxygen sometimes recognizes its own special commands, but mostly doesn't -# Not needed anymore with doxygen 1.9.3? -# try: -# sys.stdout.buffer.write("\n/**\n".encode("utf-8")) -# except Exception as e: -# print("\n*/\n\n") - -#%% -print_me = True -skip_me = False -i = 1 - -# when testing use: -# with fileinput.FileInput("..\\ChangeLog.md", -# openhook=fileinput.hook_encoded("utf-8", "surrogateescape") -# ) as input: - -with fileinput.FileInput( - openhook=fileinput.hook_encoded("utf-8", "surrogateescape") -) as input: - for line in input: - if input.isfirstline(): - # Get the file name and directory - # We'll use this to create the section id comment - file_name_dir = input.filename() - if "\\" in file_name_dir: - seper = "\\" - else: - seper = "/" - # sys.stdout.buffer.write("Separator: '{}'\n".format(seper).encode("utf-8")) - file_dir = file_name_dir.rsplit(sep=seper, maxsplit=1)[0] - file_name_ext = file_name_dir.rsplit(sep=seper, maxsplit=1)[1] - file_name = file_name_ext.rsplit(sep=".", maxsplit=1)[0] - file_ext = file_name_ext.rsplit(sep=".", maxsplit=1)[1] - # sys.stdout.buffer.write( - # "File Directory: {}, File Name: {}, File Extension: {}\n".format( - # file_dir, file_name, file_ext - # ).encode("utf-8") - # ) - # For the example walk-throughs, written in the ReadMe files, - # we want the example name, which is part of the directory. - if "examples" in file_dir and file_name == "ReadMe": - file_name = "example_" + file_dir.rsplit(sep=seper, maxsplit=1)[-1] - - # print(i, print_me, skip_me, line) - - # I'm using these comments to fence off content that is only intended for - # github mardown rendering - if "[//]: # ( Start GitHub Only )" in line: - print_me = False - - # copy the original line to work with - massaged_line = line - # Convert markdown comment tags to c++/dox style comment tags - massaged_line = re.sub(r"\[//\]: # \( @(\w+?.*) \)", r"@\1", massaged_line) - # allow thank you tags - massaged_line = massaged_line.replace("thanks to @", r"thanks to \@") - - # Convert GitHub pages url's to refs - # I'm putting the long URL in the markdown because I want the links there to - # work and go to the pages. But when feeding it to Doxygen, I want them to be - # ref's so Doxygen will both check the existence of the refs and create new - # links for them. - - # For links to sections, doxygen cuts off the first letter of the section name - # in the examples (UGH), so some acrobatics to find them - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/[\w/-]+\.html#enu_walk_(?P[\w/-]+)", - r"@ref menu_walk_\g", - massaged_line, - ) - # for classes, we need to switch camel and snake cases - class_link = re.search( - r"https://envirodiy.github.io/ModularSensors/(?:class)(?P[\w/-]+)\.html", - massaged_line, - ) - if class_link is not None: - camel_link = snake_to_camel(class_link.group("class_link")) - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/(?:class)(?P[\w/-]+)\.html", - r"@ref #" + camel_link, - massaged_line, - ) - # for groups, we need to clean out extra underscores - group_link = re.search( - r"https://envirodiy.github.io/ModularSensors/(?:group__)(?P[\w/-]+)\.html", - massaged_line, - ) - if group_link is not None: - camel_link = group_link.group("group_link").replace("__", "_") - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/(?:group__)(?P[\w/-]+)\.html", - r"@ref #" + camel_link, - massaged_line, - ) - # for examples, we need to clean out extra underscores - example_link = re.search( - r"https://envirodiy.github.io/ModularSensors/(?P[\w/-]+)_8ino-example\.html", - massaged_line, - ) - if example_link is not None: - camel_link = snake_to_camel(example_link.group("example_name")) - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/(?P[\w/-]+)_8ino-example\.html", - "@ref " + snake_to_camel(example_link.group("example_name")) + ".ino", - massaged_line, - ) - - # If it's the index itself, we want to replace with a reference to the mainpage - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/index.html#(?P[\w/-]+)", - r"@ref \g", - massaged_line, - ) - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/index.html", - "@ref mainpage", - massaged_line, - ) - - # for anything other link to the docs, we the text as it is and hope it - # lines up with a real reference - massaged_line = re.sub( - r"https://envirodiy.github.io/ModularSensors/(?P[\w/-]+)\.html", - r"@ref \g", - massaged_line, - ) - - # Add a PHP Markdown Extra style header id to the end of header sections - # use the GitHub anchor plus the file name as the section id. - # GitHub anchors for headers are the text, stripped of punctuation, - # with the spaces replaced by hyphens. - markdown_header = re.match( - r"(?P#{1,6})\s+(?P[^<>\{\}\#]+)", - massaged_line, - ) - php_extra_header_label = re.search(r"\{#(.+)\}", massaged_line) - anchor_header = re.search( - r"\w+)\">", massaged_line - ) - if ( - file_name is not None - and file_name != "ChangeLog" - and markdown_header is not None - and php_extra_header_label is None - and anchor_header is None - ): - massaged_line = ( - markdown_header.group("heading_pounds") - + " " - + markdown_header.group("section_name").strip() - + " {#" - + camel_to_snake(file_name) - + "_" - + github_slugify(markdown_header.group("section_name")) - + "}\n" - ) - - elif ( - file_name is not None - and file_name != "ChangeLog" - and markdown_header is not None - and php_extra_header_label is not None - ): - # unhide PHP Markdown Extra header id's hidding in GitHub flavored markdown comments - massaged_line = re.sub(r"", r"{#\1}", massaged_line,) - # if input.isfirstline(): - # else: - # massaged_line = ( - # markdown_header.group("heading_pounds") - # + " " - # + markdown_header.group("section_name").strip() - # + " {#" - # + camel_to_snake(file_name) - # + "_" - # + github_slugify(markdown_header.group("section_name")) - # + "}\n" - # ) - - elif ( - file_name is not None - and file_name != "ChangeLog" - and markdown_header is not None - and anchor_header is not None - ): - # convert anchors to section names - massaged_line = re.sub( - r"\w+)\">", - r"{#\g}", - massaged_line, - ) - - # Special work-arounds for the change log - if file_name is not None and file_name == "ChangeLog": - if line.startswith("# ChangeLog"): - massaged_line = "# ChangeLog {#change_log}\n" - version_re = re.match( - r"#{2}\s+(?P\[(?P[^\{\}\#]+?)\])(?P.*)", - massaged_line, - ) - version_action_re = re.match( - r"#{3}\s+(?P(?:Changed)|(?:Added)|(?:Removed)|(?:Fixed)|(?:Known Issues))", - massaged_line, - ) - if version_re is not None: - change_log_version = ( - version_re.group("version_number").strip().lower().replace(".", "-") - ) - change_log_link = version_re.group("changelog_link") - massaged_line = ( - "@section " - + camel_to_snake(file_name) - + "_" - + change_log_version - + " " - + version_re.group("version_number") - + version_re.group("version_info") - + "\n" - + "GitHub Release: " - + change_log_link - # + "\n" #NOTE: Adding the new line here would offset all doxygen line numbers - ) - if version_action_re is not None: - massaged_line = ( - massaged_line.rstrip() - + " {#" - + camel_to_snake(file_name) - + "_" - + change_log_version - + "_" - + camel_to_snake(version_action_re.group("section_name")) - + "}\n" - ) - - # convert internal hash-tag links to reference links - internal_hash_link = re.search( - r"\]\(#(?P[\w/-]+)\)", massaged_line, - ) - if internal_hash_link is not None: - massaged_line = re.sub( - r"\]\(#(?P[\w/-]+)\)", - "](@ref " - + camel_to_snake(file_name) - + "_" - + github_slugify(internal_hash_link.group("internal_anchor")) - + ")", - massaged_line, - ) - - # finally replace code blocks with doxygen's prefered code block - massaged_line = ( - massaged_line.replace("```ini", "@code{.ini}") - .replace("```cpp", "@code{.cpp}") - .replace("```", "@endcode") - ) - - # hide lines that are not printed or skipped - # write out an empty comment line to keep the line numbers identical - if skip_me or not print_me: - massaged_line = "\n" - - if ( - massaged_line.count("\n") != line.count("\n") - or line.count("\n") != 1 - or massaged_line.count("\n") != 1 - ): - raise Exception( - '\n\nNot exactly one new lines\nFile:{}\nLine Number:{}\nNew Lines in Original: {}\nOriginal Line:\n"{}"\nNew Lines after Massage: {}\nMassaged Line:\n"{}"\n\n'.format( - input.filename(), - input.filelineno(), - line.count("\n"), - line, - massaged_line.count("\n"), - massaged_line, - ) - ) - - # write out the result - try: - sys.stdout.buffer.write(massaged_line.encode("utf-8")) - except Exception as e: - print(massaged_line, end="") - - # using skip_me to skip single lines, so unset it after reading a line - if skip_me: - skip_me = False - - # a page, section, subsection, or subsubsection commands followed - # immediately with by a markdown header leads to that section appearing - # twice in the doxygen html table of contents. - # I'm putting the section markers right above the header and then will skip the header. - if re.match(r"\[//\]: # \( @mainpage", line) is not None: - skip_me = True - if re.match(r"\[//\]: # \( @page", line) is not None: - skip_me = True - if re.match(r"\[//\]: # \( @.*section", line) is not None: - skip_me = True - if re.match(r"\[//\]: # \( @paragraph", line) is not None: - skip_me = True - - # I'm using these comments to fence off content that is only intended for - # github mardown rendering - if "[//]: # ( End GitHub Only )" in line: - print_me = True - - i += 1 - -#%% -# Close the comment for doxygen -# Not needed anymore with doxygen 1.9.3? -# try: -# sys.stdout.buffer.write("\n*/\n\n".encode("utf-8")) -# except Exception as e: -# print("\n*/\n\n") From 8ecaa7f009b4554e328973cd4b3182101dae3bc1 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 15 Aug 2024 12:58:06 -0400 Subject: [PATCH 102/138] Reorder example headers Signed-off-by: Sara Damiano --- ChangeLog.md | 6 +++--- examples/DRWI_2G/DRWI_2G.ino | 14 ++++---------- examples/DRWI_DigiLTE/DRWI_DigiLTE.ino | 14 ++++---------- examples/DRWI_Mayfly1/DRWI_Mayfly1.ino | 16 +++++----------- examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino | 16 +++++----------- examples/DRWI_NoCellular/DRWI_NoCellular.ino | 14 ++++---------- examples/DRWI_SIM7080LTE/DRWI_SIM7080LTE.ino | 16 +++++----------- .../baro_rho_correction/baro_rho_correction.ino | 14 ++++---------- examples/data_saving/data_saving.ino | 14 ++++---------- examples/double_logger/double_logger.ino | 14 ++++---------- examples/logging_to_MMW/logging_to_MMW.ino | 14 ++++---------- .../logging_to_ThingSpeak.ino | 14 ++++---------- examples/menu_a_la_carte/menu_a_la_carte.ino | 14 ++++---------- examples/simple_logging/simple_logging.ino | 14 ++++---------- .../simple_logging_LearnEnviroDIY.ino | 14 ++++---------- examples/single_sensor/single_sensor.ino | 14 ++++---------- 16 files changed, 66 insertions(+), 156 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 54f53cbc7..02115b910 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,9 +1,9 @@ # ChangeLog All notable changes to this project will be documented in this file. -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) -and its stricter, better defined, brother [Common Changelog](https://common-changelog.org/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and its stricter, better defined, brother [Common Changelog](https://common-changelog.org/). + +This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). *** diff --git a/examples/DRWI_2G/DRWI_2G.ino b/examples/DRWI_2G/DRWI_2G.ino index f87e4d531..c901f66bb 100644 --- a/examples/DRWI_2G/DRWI_2G.ino +++ b/examples/DRWI_2G/DRWI_2G.ino @@ -1,16 +1,10 @@ /** ========================================================================= - * @file DRWI_2G.ino - * @brief Example for DRWI CitSci 2G sites. - * - * @author Sara Geleskie Damiano + * @example{lineno} DRWI_2G.ino * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studio Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. + * @brief Example for DRWI CitSci 2G sites. * ======================================================================= */ // ========================================================================== diff --git a/examples/DRWI_DigiLTE/DRWI_DigiLTE.ino b/examples/DRWI_DigiLTE/DRWI_DigiLTE.ino index c051cf25f..49f6e8890 100644 --- a/examples/DRWI_DigiLTE/DRWI_DigiLTE.ino +++ b/examples/DRWI_DigiLTE/DRWI_DigiLTE.ino @@ -1,16 +1,10 @@ /** ========================================================================= - * @file DRWI_DigiLTE.ino - * @brief Example for DRWI CitSci LTE sites. - * - * @author Sara Geleskie Damiano + * @example{lineno} DRWI_DigiLTE.ino * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studio Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. + * @brief Example for DRWI CitSci LTE sites. * ======================================================================= */ // ========================================================================== diff --git a/examples/DRWI_Mayfly1/DRWI_Mayfly1.ino b/examples/DRWI_Mayfly1/DRWI_Mayfly1.ino index 469752715..02cff99de 100644 --- a/examples/DRWI_Mayfly1/DRWI_Mayfly1.ino +++ b/examples/DRWI_Mayfly1/DRWI_Mayfly1.ino @@ -1,5 +1,9 @@ /** ========================================================================= - * @file DRWI_Mayfly1.ino + * @example{lineno} DRWI_Mayfly1.ino + * @copyright Stroud Water Research Center + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano + * * @brief Example for DRWI CitSci LTE sites. * * This example shows proper settings for the following configuration: @@ -7,16 +11,6 @@ * Mayfly v1.0 board * EnviroDIY SIM7080 LTE module (with Hologram SIM card) * Hydros21 CTD sensor - * - * @author Sara Geleskie Damiano - * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger - * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. * ======================================================================= */ // ========================================================================== diff --git a/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino b/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino index 5ca4cb510..022cc0638 100644 --- a/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino +++ b/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino @@ -1,5 +1,9 @@ /** ========================================================================= - * @file DRWI_Mayfly1_WiFi.ino + * @example{lineno} DRWI_Mayfly1_WiFi.ino + * @copyright Stroud Water Research Center + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano + * * @brief Example for DRWI CitSci LTE sites. * * This example shows proper settings for the following configuration: @@ -7,16 +11,6 @@ * Mayfly v1.x board * EnviroDIY ESP32 Wifi Bee module * Hydros21 CTD sensor - * - * @author Sara Geleskie Damiano - * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger - * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. * ======================================================================= */ // ========================================================================== diff --git a/examples/DRWI_NoCellular/DRWI_NoCellular.ino b/examples/DRWI_NoCellular/DRWI_NoCellular.ino index e5928cedb..ec301d231 100644 --- a/examples/DRWI_NoCellular/DRWI_NoCellular.ino +++ b/examples/DRWI_NoCellular/DRWI_NoCellular.ino @@ -1,16 +1,10 @@ /** ========================================================================= - * @file DRWI_NoCellular.ino - * @brief Example for DRWI CitSci without cellular service. - * - * @author Sara Geleskie Damiano + * @example{lineno} DRWI_NoCellular.ino * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studio Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. + * @brief Example for DRWI CitSci without cellular service. * ======================================================================= */ // ========================================================================== diff --git a/examples/DRWI_SIM7080LTE/DRWI_SIM7080LTE.ino b/examples/DRWI_SIM7080LTE/DRWI_SIM7080LTE.ino index 3b08000e3..bb1d48a69 100644 --- a/examples/DRWI_SIM7080LTE/DRWI_SIM7080LTE.ino +++ b/examples/DRWI_SIM7080LTE/DRWI_SIM7080LTE.ino @@ -1,5 +1,9 @@ /** ========================================================================= - * @file DRWI_SIM7080LTE.ino + * @example{lineno} DRWI_SIM7080LTE.ino + * @copyright Stroud Water Research Center + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano + * * @brief Example for DRWI CitSci LTE sites. * * This example shows proper settings for the following configuration: @@ -8,16 +12,6 @@ * EnviroDIY SIM7080 LTE module (with Hologram SIM card) * Hydros21 CTD sensor * Campbell Scientific OBS3+ Turbidity sensor - * - * @author Sara Geleskie Damiano - * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger - * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. * ======================================================================= */ // ========================================================================== diff --git a/examples/baro_rho_correction/baro_rho_correction.ino b/examples/baro_rho_correction/baro_rho_correction.ino index 929f08184..a41c31317 100644 --- a/examples/baro_rho_correction/baro_rho_correction.ino +++ b/examples/baro_rho_correction/baro_rho_correction.ino @@ -1,16 +1,10 @@ /** ========================================================================= - * @file baro_rho_correction.ino - * @brief Example demonstrating calculated variables. - * - * @author Sara Geleskie Damiano + * @example{lineno} baro_rho_correction.ino * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studio Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. + * @brief Example demonstrating calculated variables. * ======================================================================= */ // ========================================================================== diff --git a/examples/data_saving/data_saving.ino b/examples/data_saving/data_saving.ino index ce4e179ac..0878f2e2d 100644 --- a/examples/data_saving/data_saving.ino +++ b/examples/data_saving/data_saving.ino @@ -1,16 +1,10 @@ /** ========================================================================= - * @file data_saving.ino - * @brief Example publishing only a portion of the logged variables. - * - * @author Sara Geleskie Damiano + * @example{lineno} data_saving.ino * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studio Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. + * @brief Example publishing only a portion of the logged variables. * ======================================================================= */ // ========================================================================== diff --git a/examples/double_logger/double_logger.ino b/examples/double_logger/double_logger.ino index 85f7f2f63..c9bfef8ee 100644 --- a/examples/double_logger/double_logger.ino +++ b/examples/double_logger/double_logger.ino @@ -1,16 +1,10 @@ /** ========================================================================= - * @file double_logger.ino - * @brief Example logging at two different timing intervals - * - * @author Sara Geleskie Damiano + * @example{lineno} double_logger.ino * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studio Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. + * @brief Example logging at two different timing intervals * ======================================================================= */ // ========================================================================== diff --git a/examples/logging_to_MMW/logging_to_MMW.ino b/examples/logging_to_MMW/logging_to_MMW.ino index d48d98046..18620f659 100644 --- a/examples/logging_to_MMW/logging_to_MMW.ino +++ b/examples/logging_to_MMW/logging_to_MMW.ino @@ -1,16 +1,10 @@ /** ========================================================================= - * @file logging_to_MMW.ino - * @brief Example logging data and publishing to Monitor My Watershed. - * - * @author Sara Geleskie Damiano + * @example{lineno} logging_to_MMW.ino * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studio Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. + * @brief Example logging data and publishing to Monitor My Watershed. * ======================================================================= */ // ========================================================================== diff --git a/examples/logging_to_ThingSpeak/logging_to_ThingSpeak.ino b/examples/logging_to_ThingSpeak/logging_to_ThingSpeak.ino index 7a0044662..d490ad05a 100644 --- a/examples/logging_to_ThingSpeak/logging_to_ThingSpeak.ino +++ b/examples/logging_to_ThingSpeak/logging_to_ThingSpeak.ino @@ -1,16 +1,10 @@ /** ========================================================================= - * @file logging_to_ThingSpeak.ino - * @brief Example logging data and publishing to ThingSpeak. - * - * @author Sara Geleskie Damiano + * @example{lineno} logging_to_ThingSpeak.ino * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studio Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. + * @brief Example logging data and publishing to ThingSpeak. * ======================================================================= */ // ========================================================================== diff --git a/examples/menu_a_la_carte/menu_a_la_carte.ino b/examples/menu_a_la_carte/menu_a_la_carte.ino index 89ceb7e85..63a951df3 100644 --- a/examples/menu_a_la_carte/menu_a_la_carte.ino +++ b/examples/menu_a_la_carte/menu_a_la_carte.ino @@ -1,16 +1,10 @@ /** ========================================================================= - * @file menu_a_la_carte.ino - * @brief Example with all possible functionality. - * - * @author Sara Geleskie Damiano + * @example{lineno} menu_a_la_carte.ino * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studio Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. + * @brief Example with all possible functionality. * ======================================================================= */ // ========================================================================== diff --git a/examples/simple_logging/simple_logging.ino b/examples/simple_logging/simple_logging.ino index a31804449..f6332d89f 100644 --- a/examples/simple_logging/simple_logging.ino +++ b/examples/simple_logging/simple_logging.ino @@ -1,16 +1,10 @@ /** ========================================================================= - * @file simple_logging.ino - * @brief A simple data logging example. - * - * @author Sara Geleskie Damiano + * @example{lineno} simple_logging.ino * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studio Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. + * @brief A simple data logging example. * ======================================================================= */ // ========================================================================== diff --git a/examples/simple_logging_LearnEnviroDIY/simple_logging_LearnEnviroDIY.ino b/examples/simple_logging_LearnEnviroDIY/simple_logging_LearnEnviroDIY.ino index 5edeaa3ab..6b0cfd4c6 100644 --- a/examples/simple_logging_LearnEnviroDIY/simple_logging_LearnEnviroDIY.ino +++ b/examples/simple_logging_LearnEnviroDIY/simple_logging_LearnEnviroDIY.ino @@ -1,16 +1,10 @@ /** ========================================================================= - * @file simple_logging_LearnEnviroDIY.ino - * @brief A data logging example for the Learn EnviroDIY tutorial. - * - * @author Sara Geleskie Damiano + * @example{lineno} simple_logging_LearnEnviroDIY.ino * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studio Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. + * @brief A data logging example for the Learn EnviroDIY tutorial. * ======================================================================= */ // ========================================================================== diff --git a/examples/single_sensor/single_sensor.ino b/examples/single_sensor/single_sensor.ino index 76d3863df..d33d755bb 100644 --- a/examples/single_sensor/single_sensor.ino +++ b/examples/single_sensor/single_sensor.ino @@ -1,16 +1,10 @@ /** ========================================================================= - * @file single_sensor.ino - * @brief An example using only sensor functions and no logging. - * - * @author Sara Geleskie Damiano + * @example{lineno} single_sensor.ino * @copyright Stroud Water Research Center - * This example is published under the BSD-3 license. - * - * Build Environment: Visual Studio Code with PlatformIO - * Hardware Platform: EnviroDIY Mayfly Arduino Datalogger + * @license This example is published under the BSD-3 license. + * @author Sara Geleskie Damiano * - * DISCLAIMER: - * THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN. + * @brief An example using only sensor functions and no logging. * ======================================================================= */ // ========================================================================== From da58b30256458a64037cfaf062b803a3c51b7551 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 15 Aug 2024 13:28:52 -0400 Subject: [PATCH 103/138] Remove redundant example docs Signed-off-by: Sara Damiano --- docs/Doxyfile | 6 +- examples/DRWI_2G/DRWI_2G.ino | 4 + examples/DRWI_DigiLTE/DRWI_DigiLTE.ino | 5 ++ examples/DRWI_Mayfly1/DRWI_Mayfly1.ino | 5 ++ examples/DRWI_NoCellular/DRWI_NoCellular.ino | 5 ++ examples/DRWI_SIM7080LTE/DRWI_SIM7080LTE.ino | 5 ++ .../baro_rho_correction.ino | 4 + examples/data_saving/data_saving.ino | 5 ++ examples/double_logger/double_logger.ino | 5 ++ examples/examples.dox | 74 ------------------- examples/logging_to_MMW/logging_to_MMW.ino | 4 + .../logging_to_ThingSpeak.ino | 5 ++ examples/menu_a_la_carte/menu_a_la_carte.ino | 4 + examples/simple_logging/simple_logging.ino | 5 ++ .../simple_logging_LearnEnviroDIY.ino | 5 ++ examples/single_sensor/single_sensor.ino | 5 ++ 16 files changed, 70 insertions(+), 76 deletions(-) diff --git a/docs/Doxyfile b/docs/Doxyfile index 3b2217a8f..cd9b07517 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -547,13 +547,13 @@ EXTRACT_ALL = NO # be included in the documentation. # The default value is: NO. -EXTRACT_PRIVATE = YES +EXTRACT_PRIVATE = NO # If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual # methods of a class will be included in the documentation. # The default value is: NO. -EXTRACT_PRIV_VIRTUAL = YES +EXTRACT_PRIV_VIRTUAL = NO # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. @@ -1059,6 +1059,8 @@ EXCLUDE = ../src/ReadMe.md \ ../examples/logger_test \ ../examples/logger_test_nonew \ ../examples/YosemitechDO \ + ../examples/DRWI_2024_CTDandClarivue_LTE_20240724 \ + ../examples/DRWI_Mayfly1_Wifi_5tm_ds18b20_1 \ ../src/sensors/table.md \ ../lib \ ../boards \ diff --git a/examples/DRWI_2G/DRWI_2G.ino b/examples/DRWI_2G/DRWI_2G.ino index c901f66bb..60b5aaab0 100644 --- a/examples/DRWI_2G/DRWI_2G.ino +++ b/examples/DRWI_2G/DRWI_2G.ino @@ -5,6 +5,10 @@ * @author Sara Geleskie Damiano * * @brief Example for DRWI CitSci 2G sites. + * + * See [the walkthrough page](@ref example_drwi_2g) for detailed instructions. + * + * @m_examplenavigation{example_drwi_2g,} * ======================================================================= */ // ========================================================================== diff --git a/examples/DRWI_DigiLTE/DRWI_DigiLTE.ino b/examples/DRWI_DigiLTE/DRWI_DigiLTE.ino index 49f6e8890..10d18f5ee 100644 --- a/examples/DRWI_DigiLTE/DRWI_DigiLTE.ino +++ b/examples/DRWI_DigiLTE/DRWI_DigiLTE.ino @@ -5,6 +5,11 @@ * @author Sara Geleskie Damiano * * @brief Example for DRWI CitSci LTE sites. + * + * See [the walkthrough page](@ref example_drwi_digilte) for detailed + * instructions. + * + * @m_examplenavigation{example_drwi_digilte,} * ======================================================================= */ // ========================================================================== diff --git a/examples/DRWI_Mayfly1/DRWI_Mayfly1.ino b/examples/DRWI_Mayfly1/DRWI_Mayfly1.ino index 02cff99de..da12af231 100644 --- a/examples/DRWI_Mayfly1/DRWI_Mayfly1.ino +++ b/examples/DRWI_Mayfly1/DRWI_Mayfly1.ino @@ -11,6 +11,11 @@ * Mayfly v1.0 board * EnviroDIY SIM7080 LTE module (with Hologram SIM card) * Hydros21 CTD sensor + * + * See [the walkthrough page](@ref example_drwi_mayfly1) for detailed + * instructions. + * + * @m_examplenavigation{example_drwi_mayfly1,} * ======================================================================= */ // ========================================================================== diff --git a/examples/DRWI_NoCellular/DRWI_NoCellular.ino b/examples/DRWI_NoCellular/DRWI_NoCellular.ino index ec301d231..e132cf530 100644 --- a/examples/DRWI_NoCellular/DRWI_NoCellular.ino +++ b/examples/DRWI_NoCellular/DRWI_NoCellular.ino @@ -5,6 +5,11 @@ * @author Sara Geleskie Damiano * * @brief Example for DRWI CitSci without cellular service. + * + * See [the walkthrough page](@ref example_drwi_no_cell) for detailed + * instructions. + * + * @m_examplenavigation{example_drwi_no_cell,} * ======================================================================= */ // ========================================================================== diff --git a/examples/DRWI_SIM7080LTE/DRWI_SIM7080LTE.ino b/examples/DRWI_SIM7080LTE/DRWI_SIM7080LTE.ino index bb1d48a69..b0bddb992 100644 --- a/examples/DRWI_SIM7080LTE/DRWI_SIM7080LTE.ino +++ b/examples/DRWI_SIM7080LTE/DRWI_SIM7080LTE.ino @@ -12,6 +12,11 @@ * EnviroDIY SIM7080 LTE module (with Hologram SIM card) * Hydros21 CTD sensor * Campbell Scientific OBS3+ Turbidity sensor + * + * See [the walkthrough page](@ref example_drwi_ediylte) for detailed + * instructions. + * + * @m_examplenavigation{example_drwi_ediylte,} * ======================================================================= */ // ========================================================================== diff --git a/examples/baro_rho_correction/baro_rho_correction.ino b/examples/baro_rho_correction/baro_rho_correction.ino index a41c31317..790ac9b94 100644 --- a/examples/baro_rho_correction/baro_rho_correction.ino +++ b/examples/baro_rho_correction/baro_rho_correction.ino @@ -5,6 +5,10 @@ * @author Sara Geleskie Damiano * * @brief Example demonstrating calculated variables. + * + * See [the walkthrough page](@ref example_baro_rho) for detailed instructions. + * + * @m_examplenavigation{example_baro_rho,} * ======================================================================= */ // ========================================================================== diff --git a/examples/data_saving/data_saving.ino b/examples/data_saving/data_saving.ino index 0878f2e2d..e6f445415 100644 --- a/examples/data_saving/data_saving.ino +++ b/examples/data_saving/data_saving.ino @@ -5,6 +5,11 @@ * @author Sara Geleskie Damiano * * @brief Example publishing only a portion of the logged variables. + * + * See [the walkthrough page](@ref example_data_saving) for detailed + * instructions. + * + * @m_examplenavigation{example_data_saving,} * ======================================================================= */ // ========================================================================== diff --git a/examples/double_logger/double_logger.ino b/examples/double_logger/double_logger.ino index c9bfef8ee..d202fe2c4 100644 --- a/examples/double_logger/double_logger.ino +++ b/examples/double_logger/double_logger.ino @@ -5,6 +5,11 @@ * @author Sara Geleskie Damiano * * @brief Example logging at two different timing intervals + * + * See [the walkthrough page](@ref example_double_log) for detailed + * instructions. + * + * @m_examplenavigation{example_double_log,} * ======================================================================= */ // ========================================================================== diff --git a/examples/examples.dox b/examples/examples.dox index 864fcf6be..a7397cfa4 100644 --- a/examples/examples.dox +++ b/examples/examples.dox @@ -7,22 +7,6 @@ * @m_innerpage{example_simple_logging} * @m_innerpage{example_learn_envirodiy} */ -/** - * @example{lineno} single_sensor.ino @m_examplenavigation{example_single_sensor,} @m_footernavigation - * @brief An example using only sensor functions and no logging. - * See [the walkthrough page](@ref example_single_sensor) for detailed instructions. - */ -/** - * @example{lineno} simple_logging.ino @m_examplenavigation{example_simple_logging,} @m_footernavigation - * @brief A simple data logging example. - * See [the walkthrough page](@ref example_simple_logging) for detailed instructions. - */ -/** - * @example{lineno} simple_logging_LearnEnviroDIY.ino @m_examplenavigation{example_learn_envirodiy,} @m_footernavigation - * @brief A data logging example for the Learn EnviroDIY tutorial. - * See [the walkthrough page](@ref example_learn_envirodiy) for detailed instructions. - */ - /** * @page page_the_examples @@ -32,17 +16,6 @@ * @m_innerpage{example_mmw} * @m_innerpage{example_thingspeak} */ -/** - * @example{lineno} logging_to_MMW.ino @m_examplenavigation{example_mmw,} @m_footernavigation - * @brief Example logging data and publishing to Monitor My Watershed. - * See [the walkthrough page](@ref example_mmw) for detailed instructions. - */ -/** - * @example{lineno} logging_to_ThingSpeak.ino @m_examplenavigation{example_thingspeak,} @m_footernavigation - * @brief Example logging data and publishing to ThingSpeak. - * See [the walkthrough page](@ref example_thingspeak) for detailed instructions. - */ - /** * @page page_the_examples @@ -53,22 +26,6 @@ * @m_innerpage{example_double_log} * @m_innerpage{example_data_saving} */ -/** - * @example{lineno} baro_rho_correction.ino @m_examplenavigation{example_baro_rho,} @m_footernavigation - * @brief Example demonstrating calculated variables. - * See [the walkthrough page](@ref example_baro_rho) for detailed instructions. - */ -/** - * @example{lineno} double_logger.ino @m_examplenavigation{example_double_log,} @m_footernavigation - * @brief Example logging at two different timing intervals - * See [the walkthrough page](@ref example_double_log) for detailed instructions. - */ -/** - * @example{lineno} data_saving.ino @m_examplenavigation{example_data_saving,} @m_footernavigation - * @brief Example publishing only a portion of the logged variables. - * See [the walkthrough page](@ref example_data_saving) for detailed instructions. - */ - /** * @page page_the_examples @@ -81,32 +38,6 @@ * @m_innerpage{example_drwi_2g} * @m_innerpage{example_drwi_no_cell} */ -/** - * @example{lineno} DRWI_Mayfly1.ino @m_examplenavigation{example_drwi_mayfly1,} @m_footernavigation - * @brief Example for DRWI CitSci LTE sites with a Mayfly 1.x utilizing on-board sensors. - * See [the walkthrough page](@ref example_drwi_mayfly1) for detailed instructions. - */ -/** - * @example{lineno} DRWI_SIM7080LTE.ino @m_examplenavigation{example_drwi_ediylte,} @m_footernavigation - * @brief Example for DRWI CitSci LTE sites. - * See [the walkthrough page](@ref example_drwi_ediylte) for detailed instructions. - */ -/** - * @example{lineno} DRWI_DigiLTE.ino @m_examplenavigation{example_drwi_digilte,} @m_footernavigation - * @brief Example for DRWI CitSci LTE sites. - * See [the walkthrough page](@ref example_drwi_digilte) for detailed instructions. - */ -/** - * @example{lineno} DRWI_2G.ino @m_examplenavigation{example_drwi_2g,} @m_footernavigation - * @brief Example for DRWI CitSci 2G sites. - * See [the walkthrough page](@ref example_drwi_2g) for detailed instructions. - */ -/** - * @example{lineno} DRWI_NoCellular.ino @m_examplenavigation{example_drwi_no_cell,} @m_footernavigation - * @brief Example for DRWI CitSci without cellular service. - * See [the walkthrough page](@ref example_drwi_no_cell) for detailed instructions. - */ - /** * @page page_the_examples @@ -115,8 +46,3 @@ * [Everything at Once - a la carte](@ref examples_everything) * @m_innerpage{example_menu} */ -/** - * @example{lineno} menu_a_la_carte.ino @m_examplenavigation{example_menu,} @m_footernavigation - * @brief Example with all possible functionality. - * See [the walkthrough page](@ref example_menu) for detailed instructions. - */ diff --git a/examples/logging_to_MMW/logging_to_MMW.ino b/examples/logging_to_MMW/logging_to_MMW.ino index 18620f659..eece23667 100644 --- a/examples/logging_to_MMW/logging_to_MMW.ino +++ b/examples/logging_to_MMW/logging_to_MMW.ino @@ -5,6 +5,10 @@ * @author Sara Geleskie Damiano * * @brief Example logging data and publishing to Monitor My Watershed. + * + * See [the walkthrough page](@ref example_mmw) for detailed instructions. + * + * @m_examplenavigation{example_mmw,} * ======================================================================= */ // ========================================================================== diff --git a/examples/logging_to_ThingSpeak/logging_to_ThingSpeak.ino b/examples/logging_to_ThingSpeak/logging_to_ThingSpeak.ino index d490ad05a..e61adb42c 100644 --- a/examples/logging_to_ThingSpeak/logging_to_ThingSpeak.ino +++ b/examples/logging_to_ThingSpeak/logging_to_ThingSpeak.ino @@ -5,6 +5,11 @@ * @author Sara Geleskie Damiano * * @brief Example logging data and publishing to ThingSpeak. + * + * See [the walkthrough page](@ref example_thingspeak) for detailed + * instructions. + * + * @m_examplenavigation{example_thingspeak,} * ======================================================================= */ // ========================================================================== diff --git a/examples/menu_a_la_carte/menu_a_la_carte.ino b/examples/menu_a_la_carte/menu_a_la_carte.ino index 63a951df3..28a888ea2 100644 --- a/examples/menu_a_la_carte/menu_a_la_carte.ino +++ b/examples/menu_a_la_carte/menu_a_la_carte.ino @@ -5,6 +5,10 @@ * @author Sara Geleskie Damiano * * @brief Example with all possible functionality. + * + * See [the walkthrough page](@ref example_menu) for detailed instructions. + * + * @m_examplenavigation{example_menu,} * ======================================================================= */ // ========================================================================== diff --git a/examples/simple_logging/simple_logging.ino b/examples/simple_logging/simple_logging.ino index f6332d89f..36fe79d8e 100644 --- a/examples/simple_logging/simple_logging.ino +++ b/examples/simple_logging/simple_logging.ino @@ -5,6 +5,11 @@ * @author Sara Geleskie Damiano * * @brief A simple data logging example. + * + * See [the walkthrough page](@ref example_simple_logging) for detailed + * instructions. + * + * @m_examplenavigation{example_simple_logging,} * ======================================================================= */ // ========================================================================== diff --git a/examples/simple_logging_LearnEnviroDIY/simple_logging_LearnEnviroDIY.ino b/examples/simple_logging_LearnEnviroDIY/simple_logging_LearnEnviroDIY.ino index 6b0cfd4c6..4cb6db5d9 100644 --- a/examples/simple_logging_LearnEnviroDIY/simple_logging_LearnEnviroDIY.ino +++ b/examples/simple_logging_LearnEnviroDIY/simple_logging_LearnEnviroDIY.ino @@ -5,6 +5,11 @@ * @author Sara Geleskie Damiano * * @brief A data logging example for the Learn EnviroDIY tutorial. + * + * See [the walkthrough page](@ref example_learn_envirodiy) for detailed + * instructions. + * + * @m_examplenavigation{example_learn_envirodiy,} * ======================================================================= */ // ========================================================================== diff --git a/examples/single_sensor/single_sensor.ino b/examples/single_sensor/single_sensor.ino index d33d755bb..acfb50978 100644 --- a/examples/single_sensor/single_sensor.ino +++ b/examples/single_sensor/single_sensor.ino @@ -5,6 +5,11 @@ * @author Sara Geleskie Damiano * * @brief An example using only sensor functions and no logging. + * + * See [the walkthrough page](@ref example_single_sensor) for detailed + * instructions. + * + * @m_examplenavigation{example_single_sensor,} * ======================================================================= */ // ========================================================================== From 186b5bf6efacbaa032b4ad133e4c1d63e1380218 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 15 Aug 2024 13:59:01 -0400 Subject: [PATCH 104/138] Remove files redundant with workflow repo, update doxy fil Signed-off-by: Sara Damiano --- .../beautify_arduino_lint_log.py | 42 -------- .../build-install-doxygen.sh | 61 ----------- docs/Doxyfile | 7 +- docs/copyFunctions.py | 101 ------------------ docs/mcss-Doxyfile | 8 +- 5 files changed, 10 insertions(+), 209 deletions(-) delete mode 100644 continuous_integration/beautify_arduino_lint_log.py delete mode 100644 continuous_integration/build-install-doxygen.sh delete mode 100644 docs/copyFunctions.py diff --git a/continuous_integration/beautify_arduino_lint_log.py b/continuous_integration/beautify_arduino_lint_log.py deleted file mode 100644 index 726f573bc..000000000 --- a/continuous_integration/beautify_arduino_lint_log.py +++ /dev/null @@ -1,42 +0,0 @@ -#%% -import json -import os - -in_json = open(os.environ["GITHUB_WORKSPACE"] + "/arduino_lint.json") -arduino_lint_results = json.load(in_json) - -out_md = open(os.environ["GITHUB_WORKSPACE"] + "/arduino_lint.md", "w+") - -out_md.write("## Results of testing examples\n\n") -out_md.write(" | Path | Project Type | Result | Problems | \n") -out_md.write(" | --- | --- | --- | --- | \n") -for project in arduino_lint_results["projects"]: - fail_list = "
    " - for failed_rule in project["rules"]: - if failed_rule["result"] != "pass": - fail_list += "
  • {}{}
      ".format( - failed_rule["ID"], - " - {}".format(failed_rule["brief"]) - if failed_rule["brief"] != "" - else "", - ) - fail_list += "
    • **{}**{}
    • ".format( - failed_rule["level"], - " - {}".format(failed_rule["message"].replace("\n", "

      ")) - if failed_rule["message"] != "" - else "", - ) - fail_list += "
  • " - fail_list += "
" - out_md.write( - " | {} | {} | {} | {} | \n".format( - project["path"] - .replace(os.environ.get("GITHUB_WORKSPACE"), "") - .replace("examples\\", ""), - project["projectType"], - ":white_check_mark:" if project["summary"]["pass"] else ":x:", - fail_list, - ) - ) - -#%% diff --git a/continuous_integration/build-install-doxygen.sh b/continuous_integration/build-install-doxygen.sh deleted file mode 100644 index f67d8cd51..000000000 --- a/continuous_integration/build-install-doxygen.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -# Makes the bash script print out every command before it is executed, except echo -trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG - -# Exit with nonzero exit code if anything fails -set -e - -# install all the dependencies for make for Doxygen and m.css -sudo apt-get update -sudo apt-get -y install build-essential -sudo apt-get -y install flex -sudo apt-get -y install bison - -# install TeX Live for LaTeX formula rendering -sudo apt-get -y install texlive-base -sudo apt-get -y install texlive-latex-extra -sudo apt-get -y install texlive-fonts-extra -sudo apt-get -y install texlive-fonts-recommended - -echo "\e[32m\n\n\nCurrent TeX version...\e[0m" -tex --version -echo "\n\n\n" - -# install Graphviz for DOT class diagrams -sudo apt-get -y install graphviz - -echo "\e[32m\n\n\nCurrent graphviz version...\e[0m" -dot -v -echo "\n\n\n" - -cd $GITHUB_WORKSPACE - -if [ ! -f $GITHUB_WORKSPACE/doxygen-src/build/bin/doxygen ]; then - - # Build instructions from: https://www.stack.nl/~dimitri/doxygen/download.html - echo "\e[32mCloning doxygen repository...\e[0m" - git clone https://github.com/doxygen/doxygen.git doxygen-src --branch $DOXYGEN_VERSION --depth 1 - - cd doxygen-src - - echo "\e[32mCreate build folder...\e[0m" - mkdir build - cd build - - echo "\e[32mMake...\e[0m" - cmake -G "Unix Makefiles" .. - make - echo "\e[32mDone building doxygen.\e[0m" - echo "\e[32mdoxygen path: \e[0m" $(pwd) -fi - -echo "\e[32m\n\n\nCurrent Doxygen version...\e[0m" -$GITHUB_WORKSPACE/doxygen-src/build/bin/doxygen -v -echo "\n\n\n" - -# echo "\e[32mMove Doxygen to working directory" -# cp $GITHUB_WORKSPACE/doxygen-src/build/bin/* $GITHUB_WORKSPACE/code_docs/ModularSensors -# #make install - -cd $GITHUB_WORKSPACE/code_docs/ModularSensors diff --git a/docs/Doxyfile b/docs/Doxyfile index cd9b07517..f1c5914d1 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -74,7 +74,7 @@ PROJECT_ICON = enviroDIY_Favicon.png # entered, it will be relative to the location where Doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = ../../ModularSensorsDoxygen +OUTPUT_DIRECTORY = ../../ModularSensors_Doxygen # If the CREATE_SUBDIRS tag is set to YES then Doxygen will create up to 4096 # sub-directories (in 2 levels) under the output directory of each output format @@ -1064,7 +1064,8 @@ EXCLUDE = ../src/ReadMe.md \ ../src/sensors/table.md \ ../lib \ ../boards \ - ../variants + ../variants \ + ../continuous_integration_artifacts # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -1347,7 +1348,7 @@ IGNORE_PREFIX = # If the GENERATE_HTML tag is set to YES, Doxygen will generate HTML output # The default value is: YES. -GENERATE_HTML = NO +GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of diff --git a/docs/copyFunctions.py b/docs/copyFunctions.py deleted file mode 100644 index 3e0c64f56..000000000 --- a/docs/copyFunctions.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python -import fileinput -import re -import os -import glob -import xml.etree.ElementTree as ET -from html.parser import HTMLParser -from bs4 import BeautifulSoup - -fileDir = os.path.dirname(os.path.realpath("__file__")) -# print("Program Directory: {}".format(fileDir)) -relative_dir = "../../ModularSensorsDoxygen/m.css/" -abs_file_path = os.path.join(fileDir, relative_dir) -abs_file_path = os.path.abspath(os.path.realpath(abs_file_path)) -# print("XML Directory: {}".format(fileDir)) - -all_files = [ - f - for f in os.listdir(abs_file_path) - if os.path.isfile(os.path.join(abs_file_path, f)) - and f.endswith(".html") - and not f.endswith("fixed") -] - - -def get_section_to_paste(match: re.Match) -> str: - source_file = match.group("copy_source_file") - # print(source_file) - source_section = match.group("copy_section_id") - # print(source_section) - with open(os.path.join(abs_file_path, source_file), encoding="utf8") as fp: - soup = BeautifulSoup(fp, "html.parser") - details = soup.find(id=source_section) - # print("Details:", details, "\n\n") - link = details.find("a", class_="m-doc-self") - # print("Link:", link, "\n\n") - link["href"] = source_file + "#" + source_section - # print("Link:", link, "\n\n") - # print("Details:", details, "\n\n") - return str(details) - - # tree = ET.parse() - # root = tree.getroot() - - # for definition in root.iter("compounddef"): - # # print(definition.attrib) - # compound_id = definition.attrib["id"] - # # print(compound_id) - # # print("---") - - -# {{ AOSongAM2315_Humidity::AOSongAM2315_Humidity }} -files_to_copy_to = [] -for filename in all_files: - abs_in = os.path.join(abs_file_path, filename) - abs_out = os.path.join(abs_file_path, filename + "_fixed") - copy_paste_needed = False - # with open(os.path.join(abs_file_path, filename)) as fp: - # soup = BeautifulSoup(fp, "html.parser") - # for find in soup.find_all(string=[re.compile("\{\{")]): - # print(find.find_parent("p").a.get("href")) - - with open(abs_in, "r", encoding="utf8") as in_file: # open in readonly mode - lines = in_file.readlines() - i = 0 - new_lines = [] - for line in lines: - i += 1 - new_line = line - match = re.search( - r'{{ @endxmlonly" \ "m_enum_values_as_keywords=@xmlonly@endxmlonly" \ "m_since{2}=@since @m_class{m-label m-success m-flat} @ref changelog-\1-\2 \"since v\1.\2\"" \ - "m_deprecated_since{3}=@since deprecated in v\1.\2.\3 @deprecated" \ No newline at end of file + "m_deprecated_since{3}=@since deprecated in v\1.\2.\3 @deprecated" + +HAVE_DOT = NO +DOT_FONTNAME = Source Sans Pro +DOT_FONTSIZE = 16 From 1144626d9c99807e16c36ecf7d2db7839c98ddc9 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 15 Aug 2024 14:03:36 -0400 Subject: [PATCH 105/138] Add example dependency file Signed-off-by: Sara Damiano --- .github/workflows/verify_library_structure.yaml | 2 +- examples/example_dependencies.json | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/verify_library_structure.yaml b/.github/workflows/verify_library_structure.yaml index bf9958771..9c72b21cf 100644 --- a/.github/workflows/verify_library_structure.yaml +++ b/.github/workflows/verify_library_structure.yaml @@ -13,5 +13,5 @@ jobs: if: ${{ ! contains(github.event.head_commit.message, 'ci skip') }} uses: EnviroDIY/workflows/.github/workflows/verify_library_structure.yaml@main with: - library-manager: 'update' + library-manager: 'submit' library-compliance: 'strict' diff --git a/examples/example_dependencies.json b/examples/example_dependencies.json index 787d94b4d..d547bf4f4 100644 --- a/examples/example_dependencies.json +++ b/examples/example_dependencies.json @@ -21,6 +21,11 @@ { "name": "SoftwareSerial_ExternalInts", "version": "https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git" + }, + { + "name": "SDI-12_ExtInts", + "owner": "envirodiy", + "version": "https://github.com/EnviroDIY/Arduino-SDI-12#ExtInts" } ] } From 477192b702f90973ccb35d5f56e46d9983f680f5 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 15 Aug 2024 14:15:45 -0400 Subject: [PATCH 106/138] Fix example env names Signed-off-by: Sara Damiano --- .github/workflows/build_examples.yaml | 2 +- continuous_integration/generate_job_matrix.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_examples.yaml b/.github/workflows/build_examples.yaml index ec772ba06..b7432716c 100644 --- a/.github/workflows/build_examples.yaml +++ b/.github/workflows/build_examples.yaml @@ -13,5 +13,5 @@ jobs: if: ${{ ! contains(github.event.head_commit.message, 'ci skip') }} uses: EnviroDIY/workflows/.github/workflows/build_examples.yaml@main with: - boards_to_build: 'mayfly,megaatmega2560,zeroUSB,adafruit_feather_m0' + boards_to_build: 'mayfly,mega,zero,feather_m0' secrets: inherit diff --git a/continuous_integration/generate_job_matrix.py b/continuous_integration/generate_job_matrix.py index b8c12ebde..f2cd322d6 100644 --- a/continuous_integration/generate_job_matrix.py +++ b/continuous_integration/generate_job_matrix.py @@ -28,6 +28,7 @@ workspace_path = os.path.abspath(os.path.realpath(workspace_dir)) print(f"Workspace Path: {workspace_path}") +# %% # The examples directory examples_dir = "./examples/" examples_path = os.path.join(workspace_dir, examples_dir) @@ -652,7 +653,7 @@ def extend_pio_config(added_envs): # %% # Tack on a few more extra build configurations for the software serial libraries -for pio_env in ["Mayfly"]: +for pio_env in ["mayfly"]: arduino_serial_commands = [ start_job_commands, # 'echo "## [Extra Serials on {} with the Arduino CLI](https://github.com/EnviroDIY/ModularSensors/runs/$ACTION_RUN_ID?check_suite_focus=true#step:10:1)" >> $GITHUB_STEP_SUMMARY'.format( From 34ef181010d34ef6cbe82dfb2432d41ac6614993 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 15 Aug 2024 14:18:24 -0400 Subject: [PATCH 107/138] revert build_examples.yaml Signed-off-by: Sara Damiano --- .github/workflows/build_examples.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_examples.yaml b/.github/workflows/build_examples.yaml index b7432716c..ec772ba06 100644 --- a/.github/workflows/build_examples.yaml +++ b/.github/workflows/build_examples.yaml @@ -13,5 +13,5 @@ jobs: if: ${{ ! contains(github.event.head_commit.message, 'ci skip') }} uses: EnviroDIY/workflows/.github/workflows/build_examples.yaml@main with: - boards_to_build: 'mayfly,mega,zero,feather_m0' + boards_to_build: 'mayfly,megaatmega2560,zeroUSB,adafruit_feather_m0' secrets: inherit From 746c2ef657c88b18ed70a85cb02da19a12a128ed Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 23 Aug 2024 14:14:14 -0400 Subject: [PATCH 108/138] Fix extra flags evn name Signed-off-by: Sara Damiano --- continuous_integration/platformio_extra_flags.ini | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/continuous_integration/platformio_extra_flags.ini b/continuous_integration/platformio_extra_flags.ini index 2215cf110..e623e5d8a 100644 --- a/continuous_integration/platformio_extra_flags.ini +++ b/continuous_integration/platformio_extra_flags.ini @@ -9,7 +9,7 @@ ; http://docs.platformio.org/page/projectconf.html [env:software_wire] -extends = env:Mayfly +extends = env:mayfly build_flags = -D SDI12_EXTERNAL_PCINT -D MS_PALEOTERRA_SOFTWAREWIRE @@ -18,19 +18,19 @@ lib_deps = https://github.com/Testato/SoftwareWire.git#v1.5.1 [env:ads1015] -extends = env:Mayfly +extends = env:mayfly build_flags = -D SDI12_EXTERNAL_PCINT -D MS_USE_ADS1015 [env:sdi12_non_concurrent] -extends = env:Mayfly +extends = env:mayfly build_flags = -D SDI12_EXTERNAL_PCINT -D MS_SDI12_NON_CONCURRENT [env:AltSoftSerial] -extends = env:Mayfly +extends = env:mayfly build_flags = -D SDI12_EXTERNAL_PCINT -D BUILD_TEST_ALTSOFTSERIAL @@ -38,7 +38,7 @@ lib_deps = https://github.com/PaulStoffregen/AltSoftSerial.git [env:NeoSWSerial] -extends = env:Mayfly +extends = env:mayfly build_flags = -D SDI12_EXTERNAL_PCINT -D NEOSWSERIAL_EXTERNAL_PCINT @@ -47,7 +47,7 @@ lib_deps = https://github.com/SRGDamia1/NeoSWSerial.git [env:SoftwareSerial] -extends = env:Mayfly +extends = env:mayfly build_flags = -D SDI12_EXTERNAL_PCINT -D BUILD_TEST_SOFTSERIAL From 9b684b4a7e3a35f592696e99c64e0765877db1cc Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 23 Aug 2024 14:19:38 -0400 Subject: [PATCH 109/138] Update changelog Signed-off-by: Sara Damiano --- ChangeLog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 02115b910..fc8f7d2ec 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -12,6 +12,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Changed +- Switched to reusable workflows for CI + ### Added ### Removed From e34e87b471632cac11fd244ced03fc123546a99b Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 23 Aug 2024 17:09:58 -0400 Subject: [PATCH 110/138] Watch-dog and sleep changes based on sleepy dog Signed-off-by: Sara Damiano --- src/LoggerBase.cpp | 74 +++++++++++++++++++++------------- src/LoggerBase.h | 72 +++++++++++++++++++++++++++++++-- src/WatchDogs/WatchDogAVR.cpp | 31 ++++++++------ src/WatchDogs/WatchDogSAMD.cpp | 18 ++++----- 4 files changed, 143 insertions(+), 52 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index cfe4db7bc..6da0472a3 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -36,6 +36,7 @@ volatile bool Logger::isTestingNow = false; volatile bool Logger::startTesting = false; // Initialize the RTC for the SAMD boards using build in RTC +// Needed for static instances #if not defined(MS_SAMD_DS3231) && defined(ARDUINO_ARCH_SAMD) RTCZero Logger::zero_sleep_rtc; #endif @@ -56,10 +57,6 @@ Logger::Logger(const char* loggerID, uint16_t loggingIntervalMinutes, isTestingNow = false; startTesting = false; - // Set the initial pin values - // NOTE: Only setting values here, not the pin mode. - // The pin mode can only be set at run time, not here at compile time. - // Clear arrays for (uint8_t i = 0; i < MAX_NUMBER_SENDERS; i++) { dataPublishers[i] = nullptr; @@ -428,7 +425,6 @@ int8_t Logger::getTZOffset(void) { // This gets the current epoch time (unix time, ie, the number of seconds // from January 1, 1970 00:00:00 UTC) and corrects it to the specified time zone - uint32_t Logger::getNowEpoch(void) { // Depreciated in 0.33.0, left in for compatiblity return getNowLocalEpoch(); @@ -523,14 +519,14 @@ bool Logger::setRTClock(uint32_t UTCEpochSeconds) { // the user uint32_t set_logTZ = UTCEpochSeconds + ((uint32_t)getLoggerTimeZone()) * 3600; - MS_DBG(F(" Time for Logger supplied by NIST:"), set_logTZ, F("->"), + MS_DBG(F(" Time for Logger supplied as input:"), set_logTZ, F("->"), formatDateTime_ISO8601(set_logTZ)); // Check the current RTC time uint32_t cur_logTZ = getNowLocalEpoch(); MS_DBG(F(" Current Time on RTC:"), cur_logTZ, F("->"), formatDateTime_ISO8601(cur_logTZ)); - MS_DBG(F(" Offset between NIST and RTC:"), abs(set_logTZ - cur_logTZ)); + MS_DBG(F(" Offset between input and RTC:"), abs(set_logTZ - cur_logTZ)); // NOTE: Because we take the time to do some UTC/Local conversions and // print stuff out, the clock might end up being set up to a few @@ -762,29 +758,44 @@ void Logger::systemSleep(void) { // Disable the watch-dog timer watchDogTimer.disableWatchDog(); - // Sleep code from ArduinoLowPowerClass::sleep() - bool restoreUSBDevice = false; - // if (SERIAL_PORT_USBVIRTUAL) - // { - // USBDevice.standby(); - // } - // else - // { #ifndef USE_TINYUSB + // Detach the USB, iff not using TinyUSB + MS_DEEP_DBG(F("USBDevice.detach")); USBDevice.detach(); + MS_DEEP_DBG(F("USBDevice.end")); + USBDevice.end(); + USBDevice.standby(); #endif - restoreUSBDevice = true; - // } + +#if defined(__SAMD51__) + // PM_SLEEPCFG_SLEEPMODE_BACKUP = 0x4 + PM->SLEEPCFG.bit.SLEEPMODE = 0x4; + while (PM->SLEEPCFG.bit.SLEEPMODE != 0x4) + ; // Wait for it to take +#else // Disable systick interrupt: See // https://www.avrfreaks.net/forum/samd21-samd21e16b-sporadically-locks-and-does-not-wake-standby-sleep-mode + // Due to a hardware bug on the SAMD21, the SysTick interrupts become active + // before the flash has powered up from sleep, causing a hard fault. To + // prevent this the SysTick interrupts are disabled before entering sleep + // mode. SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; // Now go to sleep SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - __DSB(); - __WFI(); +#endif + + __DSB(); // Data sync to ensure outgoing memory accesses complete + __WFI(); // Wait for interrupt (places device in sleep mode) #elif defined ARDUINO_ARCH_AVR +// Disable USB if it exists +#ifdef USBCON + USBCON |= _BV(FRZCLK); // freeze USB clock + PLLCSR &= ~_BV(PLLE); // turn off USB PLL + USBCON &= ~_BV(USBE); // disable USB +#endif + // Set the sleep mode // In the avr/sleep.h file, the call names of these 5 sleep modes are: // SLEEP_MODE_IDLE -the least power savings @@ -839,18 +850,16 @@ void Logger::systemSleep(void) { // -- The portion below this happens on wake up, after any wake ISR's -- #if defined ARDUINO_ARCH_SAMD +#if (SAMD20_SERIES || SAMD21_SERIES) // Reattach the USB after waking // Enable systick interrupt SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; - if (restoreUSBDevice) { +#endif + // Reattach the USB #ifndef USE_TINYUSB - USBDevice.attach(); + USBDevice.init(); + USBDevice.attach(); #endif - uint32_t startTimer = millis(); - while (!SERIAL_PORT_USBVIRTUAL && ((millis() - startTimer) < 1000L)) { - // wait - } - } #endif #if defined ARDUINO_ARCH_AVR @@ -1323,8 +1332,19 @@ void Logger::begin() { MS_DBG(F("Logger is set to record at"), _loggingIntervalMinutes, F("minute intervals.")); +#if defined(ARDUINO_ARCH_SAMD) + MS_DBG(F("Disabling the USB on stnadby to lower sleep current")); + USB->DEVICE.CTRLA.bit.ENABLE = 0; // Disable the USB peripheral + while (USB->DEVICE.SYNCBUSY.bit.ENABLE) + ; // Wait for synchronization + USB->DEVICE.CTRLA.bit.RUNSTDBY = 0; // Deactivate run on standby + USB->DEVICE.CTRLA.bit.ENABLE = 1; // Enable the USB peripheral + while (USB->DEVICE.SYNCBUSY.bit.ENABLE) + ; // Wait for synchronization +#endif + MS_DBG(F( - "Setting up a watch-dog timer to fire after 5 minutes of inactivity")); + "Setting up a watch-dog timer to fire after 15 minutes of inactivity")); watchDogTimer.setupWatchDog((uint32_t)(5 * 60 * 3)); // Enable the watchdog watchDogTimer.enableWatchDog(); diff --git a/src/LoggerBase.h b/src/LoggerBase.h index 57556b40e..295190924 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -679,9 +679,6 @@ class Logger { */ static int8_t getTZOffset(void); -// This gets the current epoch time (unix time, ie, the number of seconds -// from January 1, 1970 00:00:00 UTC) and corrects it for the specified time -// zone #if (defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_SAMD_ZERO)) && \ not defined(MS_SAMD_DS3231) /** @@ -853,6 +850,75 @@ class Logger { * @anchor logger_sleep * @name Clock and Timezones * Public Functions for sleeping the logger + * + * # AVR Sleep modes + * + * In the avr/sleep.h file, the call names of these 5 sleep modes are: + * SLEEP_MODE_IDLE - the least power savings + * SLEEP_MODE_ADC + * SLEEP_MODE_PWR_SAVE + * SLEEP_MODE_STANDBY + * SLEEP_MODE_PWR_DOWN - the most power savings + * + * # SAMD21 Sleep Modes + * + * > The SAM D21/DA1 have two software-selectable sleep modes, Idle and + * > Stand-by. + * > In Idle mode, the CPU is stopped while all other functions can be kept + * > running. + * > In Stand-by mode, all clocks and functions are stopped, expect those + * > selected to continue running. + * > The device supports SleepWalking. + * > This feature allows the peripheral to wake up from sleep based on + * > predefined conditions, and thus allows the CPU to wake up only when + * > needed, e.g., when a threshold is crossed or a result is ready. + * > The Event System supports synchronous and asynchronous events, allowing + * > peripherals to receive, react to and send events even in Stand-by mode. + * + * # SAMD51 Sleep Modes + * + * > The device can be set in a sleep mode. In sleep mode, the CPU is + * > stopped and the peripherals are either active or idle, according to the + * > sleep mode depth: + * > + * > - Idle sleep mode: + * > - The CPU is stopped. + * > - Synchronous clocks are stopped except when requested. + * > - The logic is retained. + * > - Standby sleep mode: + * > - The CPU is stopped as well as the peripherals. + * > - The logic is retained, and power domain gating can be used to + * > fully or partially turn off the PDSYSRAM power domain. + * > - Hibernate sleep mode: + * > - PDCORESW power domain is turned OFF. + * > - The backup power domain is kept powered to allow few features to + * > run (RTC, 32KHz clock sources, and wake-up from external pins). + * > - The PDSYSRAM power domain can be retained according to software + * > configuration. + * > - Backup sleep mode: + * > - Only the backup domain is kept powered to allow few features to + * > run (RTC, 32KHz clock sources, and wake-up from external pins). + * > - The PDBKUPRAM power domain can be retained according to software + * > configuration. + * > - Off sleep mode: + * > - The entire device is powered off. + * + * ## Bit Settings + * | Value | Name | Definition | + * |:-----:|:---------:|:------------------------------------------:| + * | 0x0 | Reserved | - | + * | 0x1 | Reserved | - | + * | 0x2 | IDLE | CPU, AHBx, and APBx clocks are OFF | + * | 0x3 | Reserved | Reserved | + * | 0x4 | STANDBY | All Clocks are OFF | + * | 0x5 | HIBERNATE | Backup domain is ON as well as some PDRAMs | + * | 0x6 | BACKUP | Only Backup domain is powered ON | + * | 0x7 | OFF | All power domains are powered OFF | + * + * @note For the SAMD51, hibernate, backup, and off modes cause a full + * system reset on wake. Because we don't want to fully reset the device + * (and go back to the setup) on wake, the lowest power mode we can use is + * standby. */ /**@{*/ // ===================================================================== // diff --git a/src/WatchDogs/WatchDogAVR.cpp b/src/WatchDogs/WatchDogAVR.cpp index b3614b88f..ade6956a6 100644 --- a/src/WatchDogs/WatchDogAVR.cpp +++ b/src/WatchDogs/WatchDogAVR.cpp @@ -39,26 +39,28 @@ void extendedWatchDogAVR::setupWatchDog(uint32_t resetTime_s) { void extendedWatchDogAVR::enableWatchDog() { MS_DBG(F("Enabling watch dog...")); - cli(); // disable interrupts - - MCUSR = 0; // reset status register flags + // The next section is timing critical so interrupts are disabled. + cli(); + // First clear any previous watchdog reset. + MCUSR &= ~(1 << WDRF); // Put timer in interrupt-only mode: // WDTCSR - Watchdog Timer Control Register + + // Set WDCE and WDE to enable changes. + // If changes aren't enabled, we cannot change the prescaler WDTCSR |= 0b00011000; // Set Bit 4 – WDCE: Watchdog Change Enable // Set Bit 3 – WDE: Watchdog System Reset Enable // bitwise OR assignment (leaves other bits unchanged) - // Need to set the change and reset enables before changing the prescaler - WDTCSR = 0b01100001; // Set Bit 6 – WDIE: Watchdog Interrupt Enable - // Unset Bit 4 – WDCE: Watchdog Change Enable - // Unset Bit 3 – WDE: Watchdog System Reset Enable - // Set Bit 5 - WDP[3] and Bit 0 – WDP[0]: - // Watchdog Timer Prescalers 3 and 0 - 1024K cycles = 8.0s - // bitwise OR assignment (leaves other bits unchanged) - - sei(); // re-enable interrupts - // wdt_reset(); // this is not needed...timer starts without it + // Now can set the full register including the prescaler + WDTCSR = 0b01100001; + // Bit 7: WDIF (Watchdog Interrupt Flag) - 0 (Read only) + // Bit 6: WDIE (Watchdog Interrupt Enable) - 1 (Enabled) + // Bit 5: WDP3 (Watchdog Timer Prescaler) - see delay interval patterns + // Bit 4: WDCE (Watchdog Change Enable) - 0 (disable further changes) + // Bit 3: WDE (Watchdog System Reset Enable) - 0 (Clear?) + // Bits 2:0 Watchdog timer prescaler [WDP2:0] - see delay interval patterns // delay interval patterns: // 16 ms: 0bxx0xx000 @@ -68,6 +70,9 @@ void extendedWatchDogAVR::enableWatchDog() { // 4 seconds: 0bxx1xx000 // 8 seconds: 0bxx1xx001 + sei(); // re-enable interrupts + // wdt_reset(); // this is not needed...timer starts without it + extendedWatchDogAVR::_barksUntilReset = _resetTime_s / 8; MS_DBG(F("The watch dog is enabled in interrupt-only mode.")); MS_DBG(F("The interrupt will fire"), extendedWatchDogAVR::_barksUntilReset, diff --git a/src/WatchDogs/WatchDogSAMD.cpp b/src/WatchDogs/WatchDogSAMD.cpp index ff63e78bd..7163ac823 100644 --- a/src/WatchDogs/WatchDogSAMD.cpp +++ b/src/WatchDogs/WatchDogSAMD.cpp @@ -33,12 +33,6 @@ void extendedWatchDogSAMD::setupWatchDog(uint32_t resetTime_s) { extendedWatchDogSAMD::_barksUntilReset, F("times before the reset.")); - // Enable WDT early-warning interrupt - NVIC_DisableIRQ(WDT_IRQn); - NVIC_ClearPendingIRQ(WDT_IRQn); - NVIC_SetPriority(WDT_IRQn, 1); // Priority behind RTC! - NVIC_EnableIRQ(WDT_IRQn); - // Disable watchdog for config #if defined(__SAMD51__) WDT->CTRLA.reg = 0; @@ -97,27 +91,33 @@ void extendedWatchDogSAMD::setupWatchDog(uint32_t resetTime_s) { #endif + // Enable WDT early-warning interrupt + NVIC_DisableIRQ(WDT_IRQn); + NVIC_ClearPendingIRQ(WDT_IRQn); + NVIC_SetPriority(WDT_IRQn, 1); // Priority behind RTC! + NVIC_EnableIRQ(WDT_IRQn); + // Set up the watch dog control parameters #if defined(__SAMD51__) WDT->CTRLA.bit.WEN = 0; // Disable window mode #else WDT->CTRL.bit.WEN = 0; // Disable window mode #endif - waitForWDTBitSync(); // ?? Needed here ?? + waitForWDTBitSync(); #if defined(__SAMD51__) WDT->CTRLA.bit.ALWAYSON = 0; // NOT always on! #else WDT->CTRL.bit.ALWAYSON = 0; // NOT always on! #endif - waitForWDTBitSync(); // ?? Needed here ?? + waitForWDTBitSync(); WDT->CONFIG.bit.PER = 0xB; // Period = 16384 clockcycles @ 1024hz = 16 seconds WDT->EWCTRL.bit.EWOFFSET = 0xA; // Early Warning Interrupt Time Offset 0xA // = 8192 clockcycles @ 1024hz = 8 seconds WDT->INTENSET.bit.EW = 1; // Enable early warning interrupt - waitForWDTBitSync(); // ?? Needed here ?? + waitForWDTBitSync(); /*In normal mode, the Early Warning interrupt generation is defined by the Early Warning Offset in the Early Warning Control register From f36e83b25dc764411f6cbacde3de981f5dd3ac50 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 23 Aug 2024 17:10:44 -0400 Subject: [PATCH 111/138] Move board definition, fix define for Feather M0 Signed-off-by: Sara Damiano --- src/sensors/ProcessorStats.cpp | 107 +++++---------------------------- src/sensors/ProcessorStats.h | 84 ++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 92 deletions(-) diff --git a/src/sensors/ProcessorStats.cpp b/src/sensors/ProcessorStats.cpp index 2a964fadd..eb149027d 100644 --- a/src/sensors/ProcessorStats.cpp +++ b/src/sensors/ProcessorStats.cpp @@ -10,99 +10,17 @@ #include "ProcessorStats.h" -// EnviroDIY boards -#if defined(ARDUINO_AVR_ENVIRODIY_MAYFLY) -/// @brief Pretty text for the board name derived from the board's compiler -/// define. -#define BOARD "EnviroDIY Mayfly" - -// Sodaq boards -#elif defined(ARDUINO_SODAQ_EXPLORER) -#define BOARD "SODAQ ExpLoRer" -#elif defined(ARDUINO_SODAQ_AUTONOMO) -#define BOARD "SODAQ Autonomo" -#elif defined(ARDUINO_SODAQ_ONE_BETA) -#define BOARD "SODAQ ONE Beta" -#elif defined(ARDUINO_SODAQ_ONE) -#define BOARD "SODAQ ONE" -#elif defined(ARDUINO_AVR_SODAQ_MBILI) -#define BOARD "SODAQ Mbili" -#elif defined(ARDUINO_AVR_SODAQ_NDOGO) -#define BOARD "SODAQ Ndogo" -#elif defined(ARDUINO_AVR_SODAQ_TATU) -#define BOARD "SODAQ Tatu" -#elif defined(ARDUINO_AVR_SODAQ_MOJA) -#define BOARD "SODAQ Moja" - -// Adafruit boards -#elif defined(ARDUINO_AVR_FEATHER32U4) -#define BOARD "Feather 32u4" -#elif defined(ARDUINO_SAMD_FEATHER_M0) -#define BOARD "Feather M0" -#elif defined(ARDUINO_SAMD_FEATHER_M0_EXPRESS) -#define BOARD "Feather M0 Express" - -// Arduino boards -#elif defined(ARDUINO_AVR_ADK) -#define BOARD "Mega Adk" -#elif defined(ARDUINO_AVR_BT) // Bluetooth -#define BOARD "Bt" -#elif defined(ARDUINO_AVR_DUEMILANOVE) -#define BOARD "Duemilanove" -#elif defined(ARDUINO_AVR_ESPLORA) -#define BOARD "Esplora" -#elif defined(ARDUINO_AVR_ETHERNET) -#define BOARD "Ethernet" -#elif defined(ARDUINO_AVR_FIO) -#define BOARD "Fio" -#elif defined(ARDUINO_AVR_GEMMA) -#define BOARD "Gemma" -#elif defined(ARDUINO_AVR_LEONARDO) -#define BOARD "Leonardo" -#elif defined(ARDUINO_AVR_LILYPAD) -#define BOARD "Lilypad" -#elif defined(ARDUINO_AVR_LILYPAD_USB) -#define BOARD "Lilypad Usb" -#elif defined(ARDUINO_AVR_MEGA) -#define BOARD "Mega" -#elif defined(ARDUINO_AVR_MEGA2560) -#define BOARD "Mega 2560" -#elif defined(ARDUINO_AVR_MICRO) -#define BOARD "Micro" -#elif defined(ARDUINO_AVR_MINI) -#define BOARD "Mini" -#elif defined(ARDUINO_AVR_NANO) -#define BOARD "Nano" -#elif defined(ARDUINO_AVR_NG) -#define BOARD "NG" -#elif defined(ARDUINO_AVR_PRO) -#define BOARD "Pro" -#elif defined(ARDUINO_AVR_ROBOT_CONTROL) -#define BOARD "Robot Ctrl" -#elif defined(ARDUINO_AVR_ROBOT_MOTOR) -#define BOARD "Robot Motor" -#elif defined(ARDUINO_AVR_UNO) -#define BOARD "Uno" -#elif defined(ARDUINO_AVR_YUN) -#define BOARD "Yun" -#elif defined(ARDUINO_SAMD_ZERO) -#define BOARD "Zero" - -#else -#define BOARD "Unknown" -#endif - - // Need to know the Mayfly version because the battery resistor depends on it ProcessorStats::ProcessorStats(const char* version) - : Sensor(BOARD, PROCESSOR_NUM_VARIABLES, PROCESSOR_WARM_UP_TIME_MS, + : Sensor(LOGGER_BOARD, PROCESSOR_NUM_VARIABLES, PROCESSOR_WARM_UP_TIME_MS, PROCESSOR_STABILIZATION_TIME_MS, PROCESSOR_MEASUREMENT_TIME_MS, -1, -1, 1, PROCESSOR_INC_CALC_VARIABLES), _version(version) { #if defined(ARDUINO_AVR_ENVIRODIY_MAYFLY) || defined(ARDUINO_AVR_SODAQ_MBILI) _batteryPin = A6; #elif defined(ARDUINO_AVR_FEATHER32U4) || defined(ARDUINO_SAMD_FEATHER_M0) || \ - defined(ARDUINO_SAMD_FEATHER_M0_EXPRESS) + defined(SAMD_FEATHER_M0) || defined(ARDUINO_SAMD_FEATHER_M0_EXPRESS) || \ + defined(SAMD_FEATHER_M0_EXPRESS) _batteryPin = 9; #elif defined(ARDUINO_SODAQ_ONE) || defined(ARDUINO_SODAQ_ONE_BETA) || \ defined(ARDUINO_AVR_SODAQ_NDOGO) @@ -121,7 +39,7 @@ ProcessorStats::~ProcessorStats() {} String ProcessorStats::getSensorLocation(void) { - return BOARD; + return LOGGER_BOARD; } @@ -140,6 +58,7 @@ bool ProcessorStats::addSingleMeasurementResult(void) { MS_DBG(F("Getting battery voltage from pin"), _batteryPin); float sensorValue_battery = -9999; + analogRead(_batteryPin); // priming reading #if defined(ARDUINO_AVR_ENVIRODIY_MAYFLY) if (strcmp(_version, "v0.3") == 0 || strcmp(_version, "v0.4") == 0) { @@ -166,6 +85,7 @@ bool ProcessorStats::addSingleMeasurementResult(void) { #elif defined(ARDUINO_AVR_FEATHER32U4) || defined(ARDUINO_SAMD_FEATHER_M0) || \ defined(ARDUINO_SAMD_FEATHER_M0_EXPRESS) + analogRead(_batteryPin); // priming reading float measuredvbat = analogRead(_batteryPin); measuredvbat *= 2; // we divided by 2, so multiply back measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage @@ -175,22 +95,25 @@ bool ProcessorStats::addSingleMeasurementResult(void) { #elif defined(ARDUINO_SODAQ_ONE) || defined(ARDUINO_SODAQ_ONE_BETA) if (strcmp(_version, "v0.1") == 0) { // Get the battery voltage + analogRead(_batteryPin); // priming reading float rawBattery = analogRead(_batteryPin); MS_DBG(F("Raw battery pin reading in bits:"), rawBattery); sensorValue_battery = (3.3 / 1023.) * 2 * rawBattery; MS_DBG(F("Battery in Volts:"), sensorValue_battery); } - if (strcmp(_version, "v0.2") == 0) { - // Get the battery voltage - float rawBattery = analogRead(_batteryPin); - MS_DBG(F("Raw battery pin reading in bits:"), rawBattery); - sensorValue_battery = (3.3 / 1023.) * 1.47 * rawBattery; - MS_DBG(F("Battery in Volts:"), sensorValue_battery); + if (strcmp(_version, "v0.2") == 0) + analogRead(_batteryPin); // priming reading{ + // Get the battery voltage + float rawBattery = analogRead(_batteryPin); + MS_DBG(F("Raw battery pin reading in bits:"), rawBattery); + sensorValue_battery = (3.3 / 1023.) * 1.47 * rawBattery; + MS_DBG(F("Battery in Volts:"), sensorValue_battery); } #elif defined(ARDUINO_AVR_SODAQ_NDOGO) || defined(ARDUINO_SODAQ_AUTONOMO) || \ defined(ARDUINO_AVR_SODAQ_MBILI) // Get the battery voltage + analogRead(_batteryPin); // priming reading float rawBattery = analogRead(_batteryPin); MS_DBG(F("Raw battery pin reading in bits:"), rawBattery); sensorValue_battery = (3.3 / 1023.) * 1.47 * rawBattery; diff --git a/src/sensors/ProcessorStats.h b/src/sensors/ProcessorStats.h index 34b4d95ff..ec9eb68d0 100644 --- a/src/sensors/ProcessorStats.h +++ b/src/sensors/ProcessorStats.h @@ -192,6 +192,90 @@ /**@}*/ +// EnviroDIY boards +#if defined(ARDUINO_AVR_ENVIRODIY_MAYFLY) +/// @brief Pretty text for the board name derived from the board's compiler +/// define. +#define LOGGER_BOARD "EnviroDIY Mayfly" + +// Sodaq boards +#elif defined(ARDUINO_SODAQ_EXPLORER) +#define LOGGER_BOARD "SODAQ ExpLoRer" +#elif defined(ARDUINO_SODAQ_AUTONOMO) +#define LOGGER_BOARD "SODAQ Autonomo" +#elif defined(ARDUINO_SODAQ_ONE_BETA) +#define LOGGER_BOARD "SODAQ ONE Beta" +#elif defined(ARDUINO_SODAQ_ONE) +#define LOGGER_BOARD "SODAQ ONE" +#elif defined(ARDUINO_AVR_SODAQ_MBILI) +#define LOGGER_BOARD "SODAQ Mbili" +#elif defined(ARDUINO_AVR_SODAQ_NDOGO) +#define LOGGER_BOARD "SODAQ Ndogo" +#elif defined(ARDUINO_AVR_SODAQ_TATU) +#define LOGGER_BOARD "SODAQ Tatu" +#elif defined(ARDUINO_AVR_SODAQ_MOJA) +#define LOGGER_BOARD "SODAQ Moja" + +// Adafruit boards +#elif defined(ARDUINO_AVR_FEATHER32U4) +#define LOGGER_BOARD "Feather 32u4" +#elif defined(ARDUINO_SAMD_FEATHER_M0_EXPRESS) || \ + defined(ADAFRUIT_FEATHER_M0_EXPRESS) +#define LOGGER_BOARD "Feather M0 Express" +#elif defined(ARDUINO_SAMD_FEATHER_M0) || defined(ADAFRUIT_FEATHER_M0) +#define LOGGER_BOARD "Feather M0" + +// Arduino boards +#elif defined(ARDUINO_AVR_ADK) +#define LOGGER_BOARD "Mega Adk" +#elif defined(ARDUINO_AVR_BT) // Bluetooth +#define LOGGER_BOARD "Bt" +#elif defined(ARDUINO_AVR_DUEMILANOVE) +#define LOGGER_BOARD "Duemilanove" +#elif defined(ARDUINO_AVR_ESPLORA) +#define LOGGER_BOARD "Esplora" +#elif defined(ARDUINO_AVR_ETHERNET) +#define LOGGER_BOARD "Ethernet" +#elif defined(ARDUINO_AVR_FIO) +#define LOGGER_BOARD "Fio" +#elif defined(ARDUINO_AVR_GEMMA) +#define LOGGER_BOARD "Gemma" +#elif defined(ARDUINO_AVR_LEONARDO) +#define LOGGER_BOARD "Leonardo" +#elif defined(ARDUINO_AVR_LILYPAD) +#define LOGGER_BOARD "Lilypad" +#elif defined(ARDUINO_AVR_LILYPAD_USB) +#define LOGGER_BOARD "Lilypad Usb" +#elif defined(ARDUINO_AVR_MEGA) +#define LOGGER_BOARD "Mega" +#elif defined(ARDUINO_AVR_MEGA2560) +#define LOGGER_BOARD "Mega 2560" +#elif defined(ARDUINO_AVR_MICRO) +#define LOGGER_BOARD "Micro" +#elif defined(ARDUINO_AVR_MINI) +#define LOGGER_BOARD "Mini" +#elif defined(ARDUINO_AVR_NANO) +#define LOGGER_BOARD "Nano" +#elif defined(ARDUINO_AVR_NG) +#define LOGGER_BOARD "NG" +#elif defined(ARDUINO_AVR_PRO) +#define LOGGER_BOARD "Pro" +#elif defined(ARDUINO_AVR_ROBOT_CONTROL) +#define LOGGER_BOARD "Robot Ctrl" +#elif defined(ARDUINO_AVR_ROBOT_MOTOR) +#define LOGGER_BOARD "Robot Motor" +#elif defined(ARDUINO_AVR_UNO) +#define LOGGER_BOARD "Uno" +#elif defined(ARDUINO_AVR_YUN) +#define LOGGER_BOARD "Yun" +#elif defined(ARDUINO_SAMD_ZERO) +#define LOGGER_BOARD "Zero" + +#else +#define LOGGER_BOARD "Unknown" +#endif + + // The main class for the Processor // Only need a sleep and wake since these DON'T use the default of powering // up and down From cdff86720cdc0c485c49a3b61ca75fe5fcd3178f Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Fri, 23 Aug 2024 17:48:01 -0400 Subject: [PATCH 112/138] Made ds3231 default for SAMD21 Signed-off-by: Sara Damiano --- src/LoggerBase.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/LoggerBase.h b/src/LoggerBase.h index 295190924..31902dd30 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -18,6 +18,9 @@ // Debugging Statement // #define MS_LOGGERBASE_DEBUG +// Set default clock for SAMD21 as DS3231 instead of built-in RTC +#define MS_SAMD_DS3231 + #ifdef MS_LOGGERBASE_DEBUG #define MS_DEBUGGING_STD "LoggerBase" #endif From b5fdb543eabfe152b694ab90cea249bc4f9f06e7 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Sun, 25 Aug 2024 23:25:56 -0400 Subject: [PATCH 113/138] Save wake pin mode Signed-off-by: Sara Damiano --- src/LoggerBase.cpp | 11 +++++++++-- src/LoggerBase.h | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 6da0472a3..303730ce3 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -167,7 +167,8 @@ void Logger::setSDCardPins(int8_t SDCardSSPin, int8_t SDCardPowerPin) { // Sets up the wake up pin for an RTC interrupt // NOTE: This sets the pin mode but does NOT enable the interrupt! void Logger::setRTCWakePin(int8_t mcuWakePin, uint8_t wakePinMode) { - _mcuWakePin = mcuWakePin; + _mcuWakePin = mcuWakePin; + _wakePinMode = wakePinMode; if (_mcuWakePin >= 0) { pinMode(_mcuWakePin, wakePinMode); MS_DBG(F("Pin"), _mcuWakePin, F("set as RTC wake up pin")); @@ -687,6 +688,9 @@ void Logger::systemSleep(void) { return; } + // Send a message that we're getting ready + MS_DBG(F("Preparing processor for sleep. ZZzzz...")); + #if defined(MS_SAMD_DS3231) || not defined(ARDUINO_ARCH_SAMD) // Unfortunately, because of the way the alarm on the DS3231 is set up, it @@ -703,7 +707,10 @@ void Logger::systemSleep(void) { rtc.clearINTStatus(); // Set up a pin to hear clock interrupt and attach the wake ISR to it - pinMode(_mcuWakePin, INPUT_PULLUP); + MS_DBG(F("Enabling interrupts on pin"), _mcuWakePin); + // Set the pin mode, although this shouldn't really need to be re-set here + pinMode(_mcuWakePin, _wakePinMode); + // attach the interrupt enableInterrupt(_mcuWakePin, wakeISR, CHANGE); #elif defined ARDUINO_ARCH_SAMD diff --git a/src/LoggerBase.h b/src/LoggerBase.h index 31902dd30..22463960b 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -413,6 +413,15 @@ class Logger { * deep-sleep. */ int8_t _mcuWakePin = -1; + /** + * @brief The pin mode used for wake up on the clock alert pin. + * + * Must be either `INPUT` OR `INPUT_PULLUP` with an AVR board. On a SAM/D + * board `INPUT_PULLDOWN` is also an option. Optional with a default value + * of `INPUT_PULLUP`. The DS3231 has an active low interrupt, so the + * pull-up resistors should be enabled. + */ + uint8_t _wakePinMode = INPUT_PULLUP; /** * @brief Digital pin number on the mcu used to output an alert that the * logger is measuring. From f683dd8b58861e3d884c9fc6a49aeb6f2742433f Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Sun, 25 Aug 2024 23:26:28 -0400 Subject: [PATCH 114/138] Only actualy use Enable Interrupt for AVR. It's just a macro re-write for others. Signed-off-by: Sara Damiano --- src/ModSensorInterrupts.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ModSensorInterrupts.h b/src/ModSensorInterrupts.h index cb3650f81..dbb89c7cf 100644 --- a/src/ModSensorInterrupts.h +++ b/src/ModSensorInterrupts.h @@ -14,9 +14,7 @@ #ifndef SRC_MODSENSORINTERRUPTS_H_ #define SRC_MODSENSORINTERRUPTS_H_ -#if defined(__AVR__) || defined(ARDUINO_ARCH_AVR) || defined __SAM3U4E__ || \ - defined __SAM3X8E__ || defined __SAM3X8H__ || defined ARDUINO_SAMD_ZERO || \ - defined __SAMD21G18A__ || defined __SAMD21J18A__ +#if defined(__AVR__) // #define LIBCALL_ENABLEINTERRUPT // To prevent compiler/linker crashes #include // To handle external and pin change interrupts #else From ea7449ef3ad17aac19bf2141c1dc5997e4b3c510 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Sun, 25 Aug 2024 23:30:32 -0400 Subject: [PATCH 115/138] Re-wrote SAMD clock configs Signed-off-by: Sara Damiano --- src/LoggerBase.cpp | 101 +++++++++++++++-------- src/WatchDogs/WatchDogSAMD.cpp | 143 ++++++++++++++++++++++++++++----- 2 files changed, 192 insertions(+), 52 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 303730ce3..0d4ff60de 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -713,6 +713,26 @@ void Logger::systemSleep(void) { // attach the interrupt enableInterrupt(_mcuWakePin, wakeISR, CHANGE); +#if defined ARDUINO_ARCH_SAMD && not defined(__SAMD51__) + // Reconfigure the clock after attaching the interrupt + // This is needed because the attachInterrupt function will reconfigure the + // clock source for the EIC to GCLK0 every time a new interrupt is attached + // - and after being detached, reattaching the same interrupt is just like a + // new one). We need to switch the EIC source back to our configured GCLK2. + Serial.println(F("Re-attaching the EIC to GCLK2")); + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN(2) | // Select generic clock 2 + GCLK_CLKCTRL_CLKEN | // Enable the generic clock clontrol + GCLK_CLKCTRL_ID(GCM_EIC); // Feed the GCLK to the EIC + while (GCLK->STATUS.bit.SYNCBUSY) { + // Wait for synchronization + } + + // get the interrupt number associated with the pin + EExt_Interrupts in = g_APinDescription[_mcuWakePin].ulExtInt; + // Enable wakeup capability on pin in case being used during sleep + EIC->WAKEUP.reg |= (1 << in); +#endif // defined ARDUINO_ARCH_SAMD && not defined(__SAMD51__) + #elif defined ARDUINO_ARCH_SAMD // Make sure interrupts are enabled for the clock @@ -729,22 +749,11 @@ void Logger::systemSleep(void) { zero_sleep_rtc.setAlarmSeconds(59); zero_sleep_rtc.enableAlarm(zero_sleep_rtc.MATCH_SS); -#endif - - // Send one last message before shutting down serial ports - MS_DBG(F("Putting processor to sleep. ZZzzz...")); +#endif // defined(MS_SAMD_DS3231) || not defined(ARDUINO_ARCH_SAMD) -// Wait until the serial ports have finished transmitting -// This does not clear their buffers, it just waits until they are finished -// TODO(SRGDamia1): Make sure can find all serial ports -#if defined(STANDARD_SERIAL_OUTPUT) - STANDARD_SERIAL_OUTPUT.flush(); // for debugging -#endif -#if defined DEBUGGING_SERIAL_OUTPUT - DEBUGGING_SERIAL_OUTPUT.flush(); // for debugging -#endif // Stop any I2C connections + MS_DEEP_DBG(F("Ending I2C")); // This function actually disables the two-wire pin functionality and // turns off the internal pull-up resistors. Wire.end(); @@ -760,37 +769,65 @@ void Logger::systemSleep(void) { digitalWrite(SCL, LOW); #endif -#if defined ARDUINO_ARCH_SAMD - // Disable the watch-dog timer + MS_DEEP_DBG(F("Disabling the watchdog")); watchDogTimer.disableWatchDog(); -#ifndef USE_TINYUSB +// Wait until the serial ports have finished transmitting +// This does not clear their buffers, it just waits until they are finished +// TODO(SRGDamia1): Make sure can find all serial ports +#if defined(STANDARD_SERIAL_OUTPUT) + STANDARD_SERIAL_OUTPUT.flush(); // for debugging +#endif +#if defined DEBUGGING_SERIAL_OUTPUT + DEBUGGING_SERIAL_OUTPUT.flush(); // for debugging +#endif + +#if defined ARDUINO_ARCH_SAMD + +#ifndef USE_TINYUSB&& defined(USBCON) // Detach the USB, iff not using TinyUSB - MS_DEEP_DBG(F("USBDevice.detach")); + MS_DEEP_DBG(F("Detaching USB")); + Serial.flush(); // wait for any outgoing messages on Serial = USB USBDevice.detach(); - MS_DEEP_DBG(F("USBDevice.end")); USBDevice.end(); USBDevice.standby(); #endif + // Copied from Adafruit SleepDog + // Enable standby sleep mode (deepest sleep) and activate. + // Insights from Atmel ASF library. + + // NOTE: The macros SAMD20_SERIES and SAMD21_SERIES capture all of the MCU + // defines for all processors in that series. + #if defined(__SAMD51__) + // Set the sleep config // PM_SLEEPCFG_SLEEPMODE_BACKUP = 0x4 PM->SLEEPCFG.bit.SLEEPMODE = 0x4; while (PM->SLEEPCFG.bit.SLEEPMODE != 0x4) ; // Wait for it to take #else - // Disable systick interrupt: See - // https://www.avrfreaks.net/forum/samd21-samd21e16b-sporadically-locks-and-does-not-wake-standby-sleep-mode + // Don't fully power down flash when in sleep + // Adafruit SleepDog and ArduinoLowPower both do this. + // TODO: Figure out if this is really necessary + // NVMCTRL->CTRLB.bit.SLEEPPRM = NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val; + + // Disable systick interrupt // Due to a hardware bug on the SAMD21, the SysTick interrupts become active // before the flash has powered up from sleep, causing a hard fault. To // prevent this the SysTick interrupts are disabled before entering sleep // mode. SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; - // Now go to sleep + // Set the sleep config + // SCB = System Control Space Base Address + // SCR = System Control Register + // SCB_SCR_SLEEPDEEP_Msk = (1UL << 2U), the position of the deep sleep bit + // in the system control register SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; #endif + // Actually sleep __DSB(); // Data sync to ensure outgoing memory accesses complete __WFI(); // Wait for interrupt (places device in sleep mode) @@ -812,9 +849,6 @@ void Logger::systemSleep(void) { // SLEEP_MODE_PWR_DOWN -the most power savings set_sleep_mode(SLEEP_MODE_PWR_DOWN); - // Disable the watch-dog timer - watchDogTimer.disableWatchDog(); - // Temporarily disables interrupts, so no mistakes are made when writing // to the processor registers noInterrupts(); @@ -857,13 +891,12 @@ void Logger::systemSleep(void) { // -- The portion below this happens on wake up, after any wake ISR's -- #if defined ARDUINO_ARCH_SAMD -#if (SAMD20_SERIES || SAMD21_SERIES) - // Reattach the USB after waking +#if not defined(__SAMD51__) // Enable systick interrupt SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; #endif // Reattach the USB -#ifndef USE_TINYUSB +#ifndef USE_TINYUSB&& defined(USBCON) USBDevice.init(); USBDevice.attach(); #endif @@ -891,10 +924,15 @@ void Logger::systemSleep(void) { #endif + // Wake-up message + MS_DBG(F("\n\n\n... zzzZZ Processor is now awake!")); + // Re-enable the watch-dog timer + MS_DEEP_DBG(F("Re-enabling the watchdog")); watchDogTimer.enableWatchDog(); -// Re-start the I2C interface + // Re-start the I2C interface + MS_DEEP_DBG(F("Restarting I2C")); #ifdef SDA pinMode(SDA, INPUT_PULLUP); // set as input with the pull-up on #endif @@ -915,17 +953,16 @@ void Logger::systemSleep(void) { // Stop the clock from sending out any interrupts while we're awake. // There's no reason to waste thought on the clock interrupt if it // happens while the processor is awake and doing other things. + MS_DEEP_DBG(F("Unsetting the alarm on the DS2321")); rtc.disableInterrupts(); // Detach the from the pin disableInterrupt(_mcuWakePin); #elif defined ARDUINO_ARCH_SAMD + MS_DEEP_DBG(F("Unsetting the alarm on the built in RTC")); zero_sleep_rtc.disableAlarm(); #endif - // Wake-up message - MS_DBG(F("\n\n\n... zzzZZ Processor is now awake!")); - // The logger will now start the next function after the systemSleep // function in either the loop or setup } @@ -1340,7 +1377,7 @@ void Logger::begin() { F("minute intervals.")); #if defined(ARDUINO_ARCH_SAMD) - MS_DBG(F("Disabling the USB on stnadby to lower sleep current")); + MS_DBG(F("Disabling the USB on standby to lower sleep current")); USB->DEVICE.CTRLA.bit.ENABLE = 0; // Disable the USB peripheral while (USB->DEVICE.SYNCBUSY.bit.ENABLE) ; // Wait for synchronization diff --git a/src/WatchDogs/WatchDogSAMD.cpp b/src/WatchDogs/WatchDogSAMD.cpp index 7163ac823..4c176ad8f 100644 --- a/src/WatchDogs/WatchDogSAMD.cpp +++ b/src/WatchDogs/WatchDogSAMD.cpp @@ -34,6 +34,7 @@ void extendedWatchDogSAMD::setupWatchDog(uint32_t resetTime_s) { F("times before the reset.")); // Disable watchdog for config + MS_DEEP_DBG(F("Disabling the watchdog for configuration.")); #if defined(__SAMD51__) WDT->CTRLA.reg = 0; #else @@ -44,47 +45,149 @@ void extendedWatchDogSAMD::setupWatchDog(uint32_t resetTime_s) { #if defined(__SAMD51__) // SAMD51 WDT uses OSCULP32k as input clock now // section: 20.5.3 + MS_DEEP_DBG(F("Configuring the output of the ultra-low power internal 32k " + "oscillator for the watchdog.")); OSC32KCTRL->OSCULP32K.bit.EN1K = 1; // Enable out 1K (for WDT) OSC32KCTRL->OSCULP32K.bit.EN32K = 0; // Disable out 32K - waitForWDTBitSync(); - USB->DEVICE.CTRLA.bit.ENABLE = 0; // Disable the USB peripheral + MS_DEEP_DBG(F("Making sure the the USB will be disabled on standby.")); + USB->DEVICE.CTRLA.bit.ENABLE = 0; // Disable the USB peripheral for config while (USB->DEVICE.SYNCBUSY.bit.ENABLE) { // Wait for synchronization } USB->DEVICE.CTRLA.bit.RUNSTDBY = 0; // Deactivate run on standby - USB->DEVICE.CTRLA.bit.ENABLE = 1; // Enable the USB peripheral + USB->DEVICE.CTRLA.bit.ENABLE = 1; // Re-enable the USB peripheral while (USB->DEVICE.SYNCBUSY.bit.ENABLE) { // Wait for synchronization } #else // SAMD21 - // We're going to use generic clock generator *5* - // Many watch-dog examples use 2, but this conflicts with RTC-zero - // Generic clock generator 5, divisor = 32 (2^(DIV+1)) = 4 - GCLK->GENDIV.reg = GCLK_GENDIV_ID(5) | // Select Generic Clock Generator 5 + // Within the SAMD core for the SAMD21 + // SystemInit() in startup.c configures these clocks: + // 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator) or + // OSC32K (if crystalless). + // - This will be used as DFLL48M reference. + // 2) Put XOSC32K as source of Generic Clock Generator 1 + // 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer + // 0 (DFLL48M reference) + // 4) Enable DFLL48M clock + // 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. + // 6) Modify PRESCaler value of OSCM to have 8MHz + // 7) Put OSC8M as source for Generic Clock Generator 3 + // See: + // https://github.com/adafruit/ArduinoCore-samd/blob/ce20340620bfd9c545649ee5c4873888ee0475d0/cores/arduino/startup.c#L311 + + // The ZeroPowerManager library changes clocks (including the main clock + // source, GCLK_MAIN, which is always sourced from GCLKGEN[0]) to reduce + // power draw. Changing the GCLK_MAIN configuration will cause some + // functions like delay() to operate incorrectly. See: + // https://github.com/ee-quipment/ZeroPowerManager/blob/master/ZeroPowerManager.c#L170 + // To avoid any confusing with delay(), we're not going to change anything + // with GCLK0. This means we won't be in the lowest power state like that + // offered by ZeroPowerManager + // TODO: Revisit this decision + + // After a power-on reset, the clock generators for peripherals default to: + // RTC: GCLK0 + // WDT: GCLK2 + // Anything else: GCLK0 + + // We're going to configure generic clock generator 2, which is the default + // for the watchdog. RTCZero uses the same clock for the RTC. Because we're + // using identical divisors and prescalers, we can share the clock + // generator. We will also use the very same generator for the external + // nterrupt controller (EIC). + + // The watchdog must be attached to a clock source so it can tell how much + // time has passed and whether it needs to bite. + + // The external interrupt controller must be attached to a on clock to tell + // the difference between rising and falling interrupts. If the external + // interupt controller is not attached to a running clock, then interrupts + // will not work! Thus, if the clock source for interrupts is not running in + // standby, the interrupts will not be able to wake the device. In + // WInterrupts.c in the Adafruit SAMD core, generic clock generator 0 (ie + // GCLK_MAIN) is used for the EIC peripheral. See: + // https://github.com/adafruit/ArduinoCore-samd/blob/ce20340620bfd9c545649ee5c4873888ee0475d0/cores/arduino/WInterrupts.c#L56 + // We'll shift the interrupts to clock 2, configured to our liking. + + // Configure the generic clock generator divisor for generator 2 + // The divisor register must be configured before generator control register + // Generic clock generator 2, divisor = 32 (2^(DIV+1)) = 4 + GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | // Select Generic Clock Generator 5 GCLK_GENDIV_DIV(4); // Divide the clock source by 32 while (GCLK->STATUS.bit.SYNCBUSY) { // Wait for synchronization } - // Enable clock generator 5 using low-power 32.768kHz oscillator. - // With /32 divisor above, this yields 1024Hz clock. - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(5) | // Select GCLK5 - GCLK_GENCTRL_GENEN | // Enable the generic clock clontrol - GCLK_GENCTRL_SRC_OSCULP32K | // Select the ultra-low power oscillator - GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW +// Configure the generic clock generator 2 to use the 32.768kHz external or +// internal oscillator and the divisor above. +// With /32 divisor above, this yields 1024Hz clock. +// By default, the XOSC32K is stopped in standby, while the default for the +// OSCULP32K is to run in standby. +// NOTE: there is also a generic XOSC which can be attached to crystal of any +// frequency from 0.4-32MHz, but we're only supporting a 32.768kHz crystal. +#ifndef CRYSTALLESS + // If there is an external 32.768 kHz crystal, use it + + // configure the settings for the oscillator + + MS_DEEP_DBG(F("Configuring the external 32k oscillator.")); + SYSCTRL->XOSC32K.reg = + SYSCTRL_XOSC32K_ONDEMAND | // run only when demanded by a peripheral + SYSCTRL_XOSC32K_RUNSTDBY | // run the external oscillator in standby + // (iff demanded by peripheral) + SYSCTRL_XOSC32K_EN32K | // enable the 32kHz output + SYSCTRL_XOSC32K_XTALEN | // specify that the crystal is connected + // between XIN32/XOUT32 + SYSCTRL_XOSC32K_STARTUP(6) | // set the start up to 0x6 (??) + SYSCTRL_XOSC32K_ENABLE; // enable the oscillator + + // source GCLK2 from the external oscillator + MS_DEEP_DBG(F("Setting the external 32k oscillator as the clock source for " + "the generic clock generator 2.")); + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) | // Select GCLK2 + GCLK_GENCTRL_GENEN | // Enable the generic clock clontrol + GCLK_GENCTRL_SRC_XOSC32K | // Select the external crystal + GCLK_GENCTRL_RUNSTDBY | // DO run in standby GCLK_GENCTRL_DIVSEL; // Select to divide clock by the prescaler above - while (GCLK->STATUS.bit.SYNCBUSY) { - // Wait for synchronization - } - // Feed GCLK5 to WDT (Watchdog Timer) - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN_GCLK5 | // Select generic clock 5 - GCLK_CLKCTRL_CLKEN | // Enable the generic clock clontrol - GCLK_CLKCTRL_ID_WDT; // Feed the GCLK to the WDT +#else + // If there isn't an external crystal, use the built-in ultra-low power + // internal 32.768kHz oscillator. + + // NOTE: There are no settings we need to configure for ultra-low power + // internal oscillator (OSCULP32K). The only things that can be configured + // are the write lock and over-writing the factory calibration. We don't + // want to do either of those. + + // source GCLK2 from the external oscillator + MS_DEEP_DBG(F("Setting the ultra-low power internal 32k oscillator as the " + "clock source for the generic clock generator 2.")); + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) | // Select GCLK2 + GCLK_GENCTRL_GENEN | // Enable the generic clock clontrol + GCLK_GENCTRL_SRC_OSCULP32K | // built-in ultra-low power internal + // oscillator + GCLK_GENCTRL_RUNSTDBY | // DO run in standby + GCLK_GENCTRL_DIVSEL; // Select to divide clock by + // the prescaler above +#endif + while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) + ; // Wait for synchronization + + GCLK->GENCTRL.bit.RUNSTDBY = 1; // run standby + while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) + ; // Wait for synchronization + + // Feed configured GCLK2 to WDT (Watchdog Timer) **AND** the EIC (external + // interrupt controller) + MS_DEEP_DBG(F("Feeding configured GCLK2 to WDT and EIC")); + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN(2) | // Select generic clock 2 + GCLK_CLKCTRL_CLKEN | // Enable the generic clock clontrol + GCLK_CLKCTRL_ID(GCM_WDT) | // Feed the GCLK to the WDT + GCLK_CLKCTRL_ID(GCM_EIC); // Feed the GCLK to the EIC while (GCLK->STATUS.bit.SYNCBUSY) { // Wait for synchronization } From 37ee8019077ac1b1d7d7dc9e007b9deecbad07fe Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Sun, 25 Aug 2024 23:39:34 -0400 Subject: [PATCH 116/138] Update changelog, bump version Signed-off-by: Sara Damiano --- ChangeLog.md | 22 +++++++++++++++++++--- VERSION | 2 +- docs/Doxyfile | 2 +- library.json | 2 +- library.properties | 2 +- src/LoggerBase.cpp | 2 +- src/ModularSensors.h | 2 +- 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index fc8f7d2ec..f28d4a38e 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -12,8 +12,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Changed -- Switched to reusable workflows for CI - ### Added ### Removed @@ -23,6 +21,21 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm *** +## [0.35.1] + +### Changed + +- **BREAKING** Switched default clock for SAMD21 from the built-in 32bit RTC to the DS3231. +*This is not be a permanent change.* +- Switched to reusable workflows for CI + +### Fixed + +Fixed clock configuration for SAMD21 + +*** + + ## [0.35.0] ### Changed @@ -831,7 +844,10 @@ Our first release of the modular sensors library to support easily logging data *** -[Unreleased]: https://github.com/EnviroDIY/ModularSensors/compare/v0.33.4...HEAD +[Unreleased]: https://github.com/EnviroDIY/ModularSensors/compare/v0.35.1...HEAD +[0.35.1]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.35.1 +[0.35.0]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.35.0 +[0.34.0]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.34.0 [0.33.4]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.33.4 [0.33.3]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.33.3 [0.33.2]: https://github.com/EnviroDIY/ModularSensors/releases/tag/v0.33.2 diff --git a/VERSION b/VERSION index 7b52f5e51..731b95d7f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.35.0 +0.35.1 diff --git a/docs/Doxyfile b/docs/Doxyfile index f1c5914d1..2a6aa481d 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = ModularSensors # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.35.0 +PROJECT_NUMBER = 0.35.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/library.json b/library.json index 687ebf63a..a964d33f7 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "EnviroDIY_ModularSensors", - "version": "0.35.0", + "version": "0.35.1", "description": "A library that allows access to multiple sensors through a unified interface. This allows the user to simply access many sensors to log the data or send the data to data repositories like the EnviroDIY data portal.", "keywords": "modular, sensor, sensors, datalogger, logger, low power, sleeping, EnviroDIY, ModularSensors, Mayfly, WikiWatershed, Monitor My Watershed, ThingSpeak", "platforms": "atmelavr, atmelsam", diff --git a/library.properties b/library.properties index 8fd05ee5d..755fd5d22 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ModularSensors -version=0.35.0 +version=0.35.1 author=Sara Damiano , Shannon Hicks maintainer=Sara Damiano sentence=A library that allows access to multiple sensors through a unified interface. diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 0d4ff60de..3c8564458 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -719,7 +719,7 @@ void Logger::systemSleep(void) { // clock source for the EIC to GCLK0 every time a new interrupt is attached // - and after being detached, reattaching the same interrupt is just like a // new one). We need to switch the EIC source back to our configured GCLK2. - Serial.println(F("Re-attaching the EIC to GCLK2")); + MS_DEEP_DBG(F("Re-attaching the EIC to GCLK2")); GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN(2) | // Select generic clock 2 GCLK_CLKCTRL_CLKEN | // Enable the generic clock clontrol GCLK_CLKCTRL_ID(GCM_EIC); // Feed the GCLK to the EIC diff --git a/src/ModularSensors.h b/src/ModularSensors.h index 313cb58cd..6b07cc4c5 100644 --- a/src/ModularSensors.h +++ b/src/ModularSensors.h @@ -19,7 +19,7 @@ * A pre-release version will always be indicated as slightly ahead of the * EnviroDIY branch that it is based on. */ -#define MODULAR_SENSORS_VERSION "0.35.0" +#define MODULAR_SENSORS_VERSION "0.35.1" // To support interrupts #include "ModSensorInterrupts.h" From dd729449b5ac1f93c7e34b2cb38fd489c6c539d5 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 26 Aug 2024 00:53:19 -0400 Subject: [PATCH 117/138] Don't attempt bad version of KellerModbus Signed-off-by: Sara Damiano --- continuous_integration/dependencies.json | 112 +++++++++++++++++------ library.json | 6 +- 2 files changed, 87 insertions(+), 31 deletions(-) diff --git a/continuous_integration/dependencies.json b/continuous_integration/dependencies.json index 874230ccb..a59eeceec 100644 --- a/continuous_integration/dependencies.json +++ b/continuous_integration/dependencies.json @@ -1,14 +1,17 @@ { - "action_cache_version": 18, + "action_cache_version": 19, "dependencies": [ { "name": "EnviroDIY_DS3231", "owner": "envirodiy", "library id": "2079", "url": "https://github.com/EnviroDIY/Sodaq_DS3231", - "version": "~1.3.4", + "version": "~1.3.5", "note": "An Arduino library for the DS3231 RTC (Real Time Clock), based off of the Sodaq_DS3231 library.", - "authors": ["Kees Bakker", "Sara Damiano"], + "authors": [ + "Kees Bakker", + "Sara Damiano" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -19,7 +22,9 @@ "url": "https://github.com/arduino-libraries/RTCZero", "version": "~1.6.0", "note": "Functions for using the processor real time clock in SAMD21 processors", - "authors": ["Arduino"], + "authors": [ + "Arduino" + ], "frameworks": "arduino", "platforms": "atmelsam" }, @@ -30,7 +35,9 @@ "url": "https://github.com/GreyGnome/EnableInterrupt", "version": "~1.1.0", "note": "GreyGnome's EnableInterrupt - Assign an interrupt to any supported pin on all Arduinos", - "authors": ["Mike 'GreyGnome' Schwager"], + "authors": [ + "Mike 'GreyGnome' Schwager" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -41,7 +48,9 @@ "url": "https://github.com/greiman/SdFat", "version": "~2.2.3", "note": "SdFat - FAT16/FAT32 file system for SD cards.", - "authors": ["Bill Greiman"], + "authors": [ + "Bill Greiman" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -50,7 +59,10 @@ "owner": "vshymanskyy", "version": "~0.11.7", "note": "A small Arduino library for GPRS modules.", - "authors": ["Volodymyr Shymanskyy", "Sara Damiano"], + "authors": [ + "Volodymyr Shymanskyy", + "Sara Damiano" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -59,9 +71,11 @@ "owner": "knolleary", "library id": "89", "url": "https://github.com/knolleary/pubsubclient", - "version": "~2.8", + "version": "~2.8.0", "note": "A client library for MQTT messaging.", - "authors": ["Nick O'Leary"] + "authors": [ + "Nick O'Leary" + ] }, { "name": "Adafruit BusIO", @@ -70,7 +84,9 @@ "url": "https://github.com/adafruit/Adafruit_BusIO", "version": "~1.16.0", "note": "Adafruit BusIO, a dependency of other Adafruit libraries", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -81,7 +97,9 @@ "url": "https://github.com/adafruit/Adafruit_Sensor", "version": "~1.1.14", "note": "Adafruit's unified sensor library is used by their other libraries", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -91,7 +109,9 @@ "version_note": "=1.2.0", "version": "https://github.com/soligen2010/Adafruit_ADS1X15.git#7d67b451f739e9a63f40f2d6d139ab582258572b", "note": "Driver for TI's ADS1015: 12-bit Differential or Single-Ended ADC with PGA and Comparator. This fork removes bugs in the Adafruit original library.", - "authors_note": ["soligen2010"], + "authors_note": [ + "soligen2010" + ], "frameworks_note": "arduino", "platforms_note": "*" }, @@ -102,7 +122,9 @@ "url": "https://github.com/adafruit/Adafruit_AM2315", "version": "~2.2.3", "note": "AOSong AM2315 I2C Temp/Humidity Sensor Library by Adafruit", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -113,7 +135,9 @@ "url": "https://github.com/adafruit/Adafruit_BME280_Library", "version": "~2.2.4", "note": "Bosch BME280 Temp/Humidity/Pressure Sensor Library by Adafruit", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -122,7 +146,9 @@ "owner": "MartinL1", "version": "~1.0.11", "note": "An Arduino compatible, non-blocking, I2C/SPI library for the Bosch BMP388 barometer.", - "authors": ["Martin Lindupp"], + "authors": [ + "Martin Lindupp" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -133,7 +159,9 @@ "url": "https://github.com/adafruit/DHT-sensor-library", "version": "~1.4.6", "note": "AOSong DHT Sensor Library by Adafruit", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -144,7 +172,9 @@ "url": "https://github.com/adafruit/Adafruit_INA219", "version": "~1.2.3", "note": "This is a library for the Adafruit INA219 high side DC current sensor boards", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -155,7 +185,9 @@ "url": "https://github.com/adafruit/Adafruit_MPL115A2", "version": "~2.0.2", "note": "MPL115A2 Barometer Library by Adafruit", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino" }, { @@ -165,7 +197,9 @@ "url": "https://github.com/adafruit/Adafruit_SHT4X", "version": "~1.0.4", "note": "Sensirion SHT4x Library by Adafruit", - "authors": ["Adafruit"], + "authors": [ + "Adafruit" + ], "frameworks": "arduino" }, { @@ -199,7 +233,12 @@ "url": "https://github.com/milesburton/Arduino-Temperature-Control-Library", "version": "~3.11.0", "note": "DallasTemperature - Arduino Library for Dallas Temperature ICs (DS18B20, DS18S20, DS1822, DS1820)", - "authors": ["Guil Barros", "Miles Burton", "Rob Tillart", "Tim Nuewsome"], + "authors": [ + "Guil Barros", + "Miles Burton", + "Rob Tillart", + "Tim Nuewsome" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -226,14 +265,22 @@ "url": "https://github.com/NorthernWidget/MS5803", "version": "~0.1.2", "note": "General interface to MS5803-series pressure transducers", - "authors": ["Bobby Schulz", "Andrew Wickert", "Chad Sandell", "Sara Damiano"] + "authors": [ + "Bobby Schulz", + "Andrew Wickert", + "Chad Sandell", + "Sara Damiano" + ] }, { "name": "Tally_Library_I2C", "version": "https://github.com/EnviroDIY/Tally_Library.git#Dev_I2C", "version_note": "Uses `Dev_I2C` feature branch", "note": "An Arduino library for interfacing to the Project Tally Event counter from NorthernWidget.", - "authors": ["Bobby Schulz", "Anthony Aufdenkampe"], + "authors": [ + "Bobby Schulz", + "Anthony Aufdenkampe" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -244,7 +291,9 @@ "url": "https://github.com/EnviroDIY/SensorModbusMaster", "version": "~0.6.8", "note": "EnviroDIY SensorModbusMaster - Arduino library for communicating via modbus with the Arduino acting as the modbus master.", - "authors": ["Sara Damiano"], + "authors": [ + "Sara Damiano" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -253,9 +302,11 @@ "owner": "envirodiy", "library id": "5439", "url": "https://github.com/EnviroDIY/KellerModbus", - "version": "~0.2.2", + "version": "~0.2.3", "note": "Arduino library for communication with Keller pressure and water level sensors via Modbus.", - "authors": ["Anthony Aufdenkampe"] + "authors": [ + "Anthony Aufdenkampe" + ] }, { "name": "YosemitechModbus", @@ -264,7 +315,10 @@ "url": "https://github.com/EnviroDIY/YosemitechModbus", "version": "~0.4.1", "note": "Arduino library for communication with Yosemitech sensors via Modbus.", - "authors": ["Sara Damiano", "Anthony Aufdenkampe"], + "authors": [ + "Sara Damiano", + "Anthony Aufdenkampe" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" }, @@ -274,9 +328,11 @@ "url": "https://github.com/EnviroDIY/GroPointModbus.git", "version": "~0.1.0", "note": "A library to use an Arduino as a master to control and communicate via modbus with GroPoint soil moisture sensors. ", - "authors": ["Anthony Aufdenkampe"], + "authors": [ + "Anthony Aufdenkampe" + ], "frameworks": "arduino", "platforms": "atmelavr, atmelsam" } ] -} +} \ No newline at end of file diff --git a/library.json b/library.json index a964d33f7..a8518e866 100644 --- a/library.json +++ b/library.json @@ -67,7 +67,7 @@ "owner": "envirodiy", "library id": "2079", "url": "https://github.com/EnviroDIY/Sodaq_DS3231", - "version": "~1.3.4", + "version": "~1.3.5", "note": "An Arduino library for the DS3231 RTC (Real Time Clock), based off of the Sodaq_DS3231 library.", "authors": ["Kees Bakker", "Sara Damiano"], "frameworks": "arduino", @@ -120,7 +120,7 @@ "owner": "knolleary", "library id": "89", "url": "https://github.com/knolleary/pubsubclient", - "version": "~2.8", + "version": "~2.8.0", "note": "A client library for MQTT messaging.", "authors": ["Nick O'Leary"] }, @@ -314,7 +314,7 @@ "owner": "envirodiy", "library id": "5439", "url": "https://github.com/EnviroDIY/KellerModbus", - "version": "~0.2.2", + "version": "~0.2.3", "note": "Arduino library for communication with Keller pressure and water level sensors via Modbus.", "authors": ["Anthony Aufdenkampe"] }, From a3f5dada096dfec5f74a79f37d8fceedb3c468c6 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 26 Aug 2024 01:13:10 -0400 Subject: [PATCH 118/138] Fix release inputs Signed-off-by: Sara Damiano --- .github/workflows/prepare_release.yaml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/prepare_release.yaml b/.github/workflows/prepare_release.yaml index 62f618b3e..6bcf69a7e 100644 --- a/.github/workflows/prepare_release.yaml +++ b/.github/workflows/prepare_release.yaml @@ -6,6 +6,12 @@ on: paths: - 'VERSION' # Push events when the VERSION file changes workflow_dispatch: + inputs: + include_dependencies: + description: 'True to include a zip file with dependencies in the release' + required: false + type: boolean + default: true name: Create a New Release @@ -45,5 +51,4 @@ jobs: uses: EnviroDIY/workflows/.github/workflows/prepare_release.yaml@main secrets: inherit with: - library-manager: 'update' - library-compliance: 'strict' + include_dependencies: ${{ ( true ) || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true') }} From eb03a690fed68ec5fc3a2e35fb335656351f5ec4 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 26 Aug 2024 02:24:24 -0400 Subject: [PATCH 119/138] Fixed define check Signed-off-by: Sara Damiano --- src/LoggerBase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 3c8564458..07078d116 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -785,7 +785,7 @@ void Logger::systemSleep(void) { #if defined ARDUINO_ARCH_SAMD -#ifndef USE_TINYUSB&& defined(USBCON) +#if not defined(USE_TINYUSB) && defined(USBCON) // Detach the USB, iff not using TinyUSB MS_DEEP_DBG(F("Detaching USB")); Serial.flush(); // wait for any outgoing messages on Serial = USB @@ -896,7 +896,7 @@ void Logger::systemSleep(void) { SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; #endif // Reattach the USB -#ifndef USE_TINYUSB&& defined(USBCON) +#if not defined(USE_TINYUSB) && defined(USBCON) USBDevice.init(); USBDevice.attach(); #endif From b1f45a1d284a715774cd5ff321c0a4ba73bef625 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 5 Sep 2024 16:28:06 -0400 Subject: [PATCH 120/138] typo fix Signed-off-by: Sara Damiano --- src/LoggerBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 72c5b4029..6d149f06d 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -288,7 +288,7 @@ String Logger::formatValueStringAtI(uint8_t position_i, float value) { // ===================================================================== // // Set up communications -// Adds a loggerModem objct to the logger +// Adds a loggerModem object to the logger // loggerModem = TinyGSM modem + TinyGSM client + Modem On Off void Logger::attachModem(loggerModem& modem) { _logModem = &modem; From 7561c6ced2e288820e11d70dec46ed9aa512d804 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 16 Sep 2024 10:35:08 -0400 Subject: [PATCH 121/138] Add macro for NIST response bytes Signed-off-by: Sara Damiano --- src/modems/DigiXBeeWifi.cpp | 6 +-- src/modems/LoggerModemMacros.h | 90 ++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 46 deletions(-) diff --git a/src/modems/DigiXBeeWifi.cpp b/src/modems/DigiXBeeWifi.cpp index 21a6d812b..47a7b4896 100644 --- a/src/modems/DigiXBeeWifi.cpp +++ b/src/modems/DigiXBeeWifi.cpp @@ -405,15 +405,15 @@ uint32_t DigiXBeeWifi::getNISTTime(void) { // Wait up to 5 seconds for a response if (connectionMade) { uint32_t start = millis(); - while (gsmClient && gsmClient.available() < 4 && + while (gsmClient && gsmClient.available() < NIST_RESPONSE_BYTES && millis() - start < 5000L) { // wait } if (gsmClient.available() >= 4) { MS_DBG(F("NIST responded after"), millis() - start, F("ms")); - byte response[4] = {0}; - gsmClient.read(response, 4); + byte response[NIST_RESPONSE_BYTES] = {0}; + gsmClient.read(response, NIST_RESPONSE_BYTES); gsmClient.stop(); return parseNISTBytes(response); } else { diff --git a/src/modems/LoggerModemMacros.h b/src/modems/LoggerModemMacros.h index 1d260bb87..37760b206 100644 --- a/src/modems/LoggerModemMacros.h +++ b/src/modems/LoggerModemMacros.h @@ -458,13 +458,16 @@ * @brief The port hosting the NIST "time" protocol (37) */ #define TIME_PROTOCOL_PORT 37 +/** + * @brief The size of the NIST response from the "time" protocol, in bytes. + */ +#define NIST_RESPONSE_BYTES 4 -// Try up to 4 NIST IP addresses attempting to get a timestamp from NIST #if !defined NIST_SERVER_RETRYS || defined(DOXYGEN) /** * @brief The number of retry attempts when connecting to the NIST server. */ -#define NIST_SERVER_RETRYS 4 +#define NIST_SERVER_RETRYS 12 #endif // NIST_SERVER_RETRYS /** @@ -486,47 +489,48 @@ * subclass. * */ -#define MS_MODEM_GET_NIST_TIME(specificModem) \ - uint32_t specificModem::getNISTTime(void) { \ - /** Check for and bail if not connected to the internet. */ \ - if (!isInternetAvailable()) { \ - MS_DBG(F("No internet connection, cannot connect to NIST.")); \ - return 0; \ - } \ - \ - /** Try up to 12 times to get a timestamp from NIST. */ \ - for (uint8_t i = 0; i < 12; i++) { \ - while (millis() < _lastNISTrequest + 4000) { /* wait */ \ - } \ - \ - /** Make TCP connection. */ \ - MS_DBG(F("\nConnecting to NIST daytime Server")); \ - bool connectionMade = gsmClient.connect("time.nist.gov", \ - TIME_PROTOCOL_PORT, 15); \ - \ - /** Wait up to 5 seconds for a response. */ \ - if (connectionMade) { \ - uint32_t start = millis(); \ - while (gsmClient && \ - gsmClient.available() < NIST_SERVER_RETRYS && \ - millis() - start < 5000L) {} \ - \ - if (gsmClient.available() >= 4) { \ - MS_DBG(F("NIST responded after"), millis() - start, \ - F("ms")); \ - byte response[4] = {0}; \ - gsmClient.read(response, 4); \ - if (gsmClient.connected()) gsmClient.stop(); \ - return parseNISTBytes(response); \ - } else { \ - MS_DBG(F("NIST Time server did not respond!")); \ - if (gsmClient.connected()) gsmClient.stop(); \ - } \ - } else { \ - MS_DBG(F("Unable to open TCP to NIST!")); \ - } \ - } \ - return 0; \ +#define MS_MODEM_GET_NIST_TIME(specificModem) \ + uint32_t specificModem::getNISTTime(void) { \ + /** Check for and bail if not connected to the internet. */ \ + if (!isInternetAvailable()) { \ + MS_DBG(F("No internet connection, cannot connect to NIST.")); \ + return 0; \ + } \ + \ + /** Try up to 12 times to get a timestamp from NIST. */ \ + for (uint8_t i = 0; i < 12; i++) { \ + while (millis() < _lastNISTrequest + 4000) { /* wait */ \ + } \ + \ + /** Make TCP connection. */ \ + MS_DBG(F("\nConnecting to NIST daytime Server")); \ + bool connectionMade = gsmClient.connect("time.nist.gov", \ + TIME_PROTOCOL_PORT, 15); \ + \ + /** Wait up to 5 seconds for a response. */ \ + if (connectionMade) { \ + uint32_t start = millis(); \ + while (gsmClient && \ + gsmClient.available() < NIST_SERVER_RETRYS && \ + millis() - start < 5000L) {} \ + \ + if (gsmClient.available() >= NIST_RESPONSE_BYTES) { \ + MS_DBG(F("NIST responded after"), millis() - start, \ + F("ms")); \ + byte response[NIST_RESPONSE_BYTES] = {0}; \ + gsmClient.read(response, NIST_RESPONSE_BYTES); \ + if (gsmClient.connected()) gsmClient.stop(); \ + uint32_t nistParsed = parseNISTBytes(response); \ + if (nistParsed != 0) { return parseNISTBytes(response); } \ + } else { \ + MS_DBG(F("NIST Time server did not respond!")); \ + if (gsmClient.connected()) gsmClient.stop(); \ + } \ + } else { \ + MS_DBG(F("Unable to open TCP to NIST!")); \ + } \ + } \ + return 0; \ } #if defined(TINY_GSM_MODEM_XBEE) || defined(TINY_GSM_MODEM_ESP8266) From 3354e342238fc684da217722e60ce99bb463e4f6 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 16 Sep 2024 10:35:37 -0400 Subject: [PATCH 122/138] Fix small typos Signed-off-by: Sara Damiano --- src/LoggerBase.cpp | 2 +- src/LoggerBase.h | 2 +- src/sensors/EverlightALSPT19.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 6d149f06d..93b7b420d 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -704,7 +704,7 @@ bool Logger::checkMarkedInterval(void) { // Set up the Interrupt Service Request for waking // In this case, we're doing nothing, we just want the processor to wake // This must be a static function (which means it can only call other static -// funcions.) +// functions.) void Logger::wakeISR(void) { MS_DEEP_DBG(F("\nClock interrupt!")); } diff --git a/src/LoggerBase.h b/src/LoggerBase.h index 93764c15d..f163e8be8 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -895,7 +895,7 @@ class Logger { * * In this case, we're doing nothing, we just want the processor to wake. * This must be a static function (which means it can only call other static - * funcions.) + * functions.) */ static void wakeISR(void); diff --git a/src/sensors/EverlightALSPT19.cpp b/src/sensors/EverlightALSPT19.cpp index 9f885f87f..59f262fee 100644 --- a/src/sensors/EverlightALSPT19.cpp +++ b/src/sensors/EverlightALSPT19.cpp @@ -73,7 +73,7 @@ bool EverlightALSPT19::addSingleMeasurementResult(void) { // resistance is entered in kΩ and we want µA current_val = (volt_val / (_loadResistor * 1000)) * 1e6; // convert current to illuminance - // from sensor datasheet, typical 200µA current for1000 Lux + // from sensor datasheet, typical 200µA current for 1000 Lux lux_val = current_val * (1000. / 200.); From dd0e259d4b6683a3bd34ad24a3d13b356e78f6a0 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 16 Sep 2024 10:40:50 -0400 Subject: [PATCH 123/138] Fix Keller dependency version Signed-off-by: Sara Damiano --- continuous_integration/dependencies.json | 2 +- library.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/continuous_integration/dependencies.json b/continuous_integration/dependencies.json index a6eae8fb3..e586b16cd 100644 --- a/continuous_integration/dependencies.json +++ b/continuous_integration/dependencies.json @@ -253,7 +253,7 @@ "owner": "envirodiy", "library id": "5439", "url": "https://github.com/EnviroDIY/KellerModbus", - "version": "~0.2.2", + "version": "~0.2.3", "note": "Arduino library for communication with Keller pressure and water level sensors via Modbus.", "authors": ["Anthony Aufdenkampe"] }, diff --git a/library.json b/library.json index f7aa743eb..73e8ab466 100644 --- a/library.json +++ b/library.json @@ -314,7 +314,7 @@ "owner": "envirodiy", "library id": "5439", "url": "https://github.com/EnviroDIY/KellerModbus", - "version": "~0.2.2", + "version": "~0.2.3", "note": "Arduino library for communication with Keller pressure and water level sensors via Modbus.", "authors": ["Anthony Aufdenkampe"] }, From 8646b2c376bce5cb677f91bb794c4fa04c7c7787 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 16 Sep 2024 13:15:49 -0400 Subject: [PATCH 124/138] Clean some docs for use with reusable workflows Signed-off-by: Sara Damiano --- .gitignore | 1 + .../check_component_inclusion.py | 12 ++--- docs/Doxyfile | 8 +--- .../DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino | 2 + .../LTExBee_FirstConnection.ino | 4 +- .../LTExBee_FirstConnectionBypass.ino | 4 +- extras/Stream_Debug/Stream_Debug.ino | 4 +- extras/extras.dox | 44 ------------------- extras/i2c_scanner/i2c_scanner.ino | 4 +- extras/i2c_warmUp/i2c_warmUp.ino | 4 +- .../interrupt_counter/interrupt_counter.ino | 4 +- extras/mega_serial_spy/mega_serial_spy.ino | 4 +- extras/oneWireSearch/oneWireSearch.ino | 10 +++-- extras/powerOn/powerOn.ino | 4 +- extras/resetBee/resetBee.ino | 4 +- .../sdi12_address_change.ino | 4 +- src/LoggerBase.h | 4 +- src/ModSensorInterrupts.h | 8 ++++ 18 files changed, 58 insertions(+), 71 deletions(-) diff --git a/.gitignore b/.gitignore index ec6909142..f78bb1753 100644 --- a/.gitignore +++ b/.gitignore @@ -106,3 +106,4 @@ runDoxygen_archive.bat generateKeywords.bat update_path.bat pio_common_libdeps.ini +ex_one_offs/* diff --git a/continuous_integration/check_component_inclusion.py b/continuous_integration/check_component_inclusion.py index 485926cf5..ef4a243a4 100644 --- a/continuous_integration/check_component_inclusion.py +++ b/continuous_integration/check_component_inclusion.py @@ -1,4 +1,4 @@ -#%% +# %% import glob import re import sys @@ -15,7 +15,7 @@ header_files = modemHeaderFiles + sensorHeaderFiles + publisherHeaderFiles # print(header_files) -#%% function to find the lowest level class +# %% function to find the lowest level class def find_subclasses(class_name): subclass_pattern = r"class[\s\n]+(\w+)[\s\n]+:[\s\n]+public[\s\n]+" + re.escape( class_name @@ -63,7 +63,7 @@ def camel_to_snake(name, lower_case=True): return name_lower.upper() -#%% +# %% # make sure class names match file names class_pattern = re.compile(r"^\s*class[\s\n]+(\w+)[\s\n]", re.MULTILINE) @@ -86,7 +86,7 @@ def camel_to_snake(name, lower_case=True): ) ) -#%% +# %% # make sure there are examples of all classes in the menu example must_doc_classes = [] @@ -140,7 +140,7 @@ def camel_to_snake(name, lower_case=True): ) # print(must_doc_classes) -#%% +# %% menu_example_file = open( os.path.join(script_dir, "../examples/menu_a_la_carte/menu_a_la_carte.ino"), mode="r", @@ -222,3 +222,5 @@ def print_missing(missing_things): }, } sys.exit(1) +else: + print("All classes, flags, snippets, and walkthroughs seem to be documented") diff --git a/docs/Doxyfile b/docs/Doxyfile index 8caaaeb18..5f44b6603 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1066,12 +1066,6 @@ EXCLUDE = ../src/ReadMe.md \ ../boards \ ../variants \ ../continuous_integration_artifacts -======= - ../continuous_integration_artifacts \ - ../lib \ - ../boards \ - ../variants ->>>>>>> Stashed changes # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -2463,7 +2457,7 @@ MACRO_EXPANSION = YES # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -EXPAND_ONLY_PREDEF = YES +EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES, the include files in the # INCLUDE_PATH will be searched if a #include is found. diff --git a/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino b/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino index 022cc0638..234e2fb42 100644 --- a/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino +++ b/examples/DRWI_Mayfly1_WiFi/DRWI_Mayfly1_WiFi.ino @@ -11,6 +11,8 @@ * Mayfly v1.x board * EnviroDIY ESP32 Wifi Bee module * Hydros21 CTD sensor + * + * @m_examplenavigation{example_drwi_mayfly1_wifi,} * ======================================================================= */ // ========================================================================== diff --git a/extras/LTExBee_FirstConnection/LTExBee_FirstConnection.ino b/extras/LTExBee_FirstConnection/LTExBee_FirstConnection.ino index cad9ac134..fbd762fe3 100644 --- a/extras/LTExBee_FirstConnection/LTExBee_FirstConnection.ino +++ b/extras/LTExBee_FirstConnection/LTExBee_FirstConnection.ino @@ -1,7 +1,9 @@ /** ========================================================================= - * @file LTExBee_FirstConnection.ino + * @example{lineno} LTExBee_FirstConnection.ino * @brief Testing sketch to set up a never-previously-connected LTE XBee running * in standard (transparent) mode. + * + * @m_examplenavigation{page_extra_helper_sketches,} * ======================================================================= */ #define TINY_GSM_MODEM_XBEE diff --git a/extras/LTExBee_FirstConnectionBypass/LTExBee_FirstConnectionBypass.ino b/extras/LTExBee_FirstConnectionBypass/LTExBee_FirstConnectionBypass.ino index 7d8b3e7f4..ec82a57a1 100644 --- a/extras/LTExBee_FirstConnectionBypass/LTExBee_FirstConnectionBypass.ino +++ b/extras/LTExBee_FirstConnectionBypass/LTExBee_FirstConnectionBypass.ino @@ -1,7 +1,9 @@ /** ========================================================================= - * @file LTExBee_FirstConnectionBypass.ino + * @example{lineno} LTExBee_FirstConnectionBypass.ino * @brief Testing sketch to set up a never-previously-connected LTE XBee running * in bypass mode. + * + * @m_examplenavigation{page_extra_helper_sketches,} * ======================================================================= */ #define TINY_GSM_MODEM_SARAR4 diff --git a/extras/Stream_Debug/Stream_Debug.ino b/extras/Stream_Debug/Stream_Debug.ino index 9c2700a82..3efff6a6e 100644 --- a/extras/Stream_Debug/Stream_Debug.ino +++ b/extras/Stream_Debug/Stream_Debug.ino @@ -1,7 +1,9 @@ /** ========================================================================= - * @file Stream_Debug.ino + * @example{lineno} Stream_Debug.ino * @brief Testing sketch to run StreamDebugger to copy text from one serial * output to another. + * + * @m_examplenavigation{page_extra_helper_sketches,} * ======================================================================= */ #include diff --git a/extras/extras.dox b/extras/extras.dox index ec820a376..6585d0cde 100644 --- a/extras/extras.dox +++ b/extras/extras.dox @@ -3,47 +3,3 @@ * * @brief Contains extra sketches for testing and configuring new sensors. */ -/** - * @example{lineno} powerOn.ino - * @brief Testing sketch that simply turns on power to the sensors on the Mayfly. - */ -/** - * @example{lineno} oneWireSearch.ino - * @brief Testing sketch to scan for 1-Wire devices + code snippet generator - */ -/** - * @example{lineno} i2c_scanner.ino - * @brief Testing sketch to scan for attached I2C devices - */ -/** - * @example{lineno} i2c_warmUp.ino - * @brief Testing sketch to see how long an attached I2C device takes to begin to respond to commands. - */ -/** - * @example{lineno} interrupt_counter.ino - * @brief Testing sketch counting pin change interrupts. - */ -/** - * @example{lineno} resetBee.ino - * @brief Testing sketch to fully reset an XBee - */ -/** - * @example{lineno} LTExBee_FirstConnection.ino - * @brief Testing sketch to set up a never-previously-connected LTE XBee running in standard (transparent) mode. - */ -/** - * @example{lineno} LTExBee_FirstConnectionBypass.ino - * @brief Testing sketch to set up a never-previously-connected LTE XBee running in bypass mode. - */ -/** - * @example{lineno} mega_serial_spy.ino - * @brief Testing sketch to run on an Arduino Mega to print all output from connected serial ports to the terminal. - */ -/** - * @example{lineno} sdi12_address_change.ino - * @brief Copy of SDI-12 Example B: Changing the Address of your SDI-12 Sensor - */ -/** - * @example{lineno} Stream_Debug.ino - * @brief Testing sketch to run StreamDebugger to copy text from one serial output to another. - */ diff --git a/extras/i2c_scanner/i2c_scanner.ino b/extras/i2c_scanner/i2c_scanner.ino index 21ebc2ba8..1b4e98101 100644 --- a/extras/i2c_scanner/i2c_scanner.ino +++ b/extras/i2c_scanner/i2c_scanner.ino @@ -1,5 +1,5 @@ /** ========================================================================= - * @file i2c_scanner.ino + * @example{lineno} i2c_scanner.ino * @brief Testing sketch to scan for attached I2C devices * * Version 1 @@ -26,6 +26,8 @@ * * This sketch tests the standard 7-bit addresses. * Devices with higher bit address might not be seen properly. + * + * @m_examplenavigation{page_extra_helper_sketches,} * ======================================================================= */ #include diff --git a/extras/i2c_warmUp/i2c_warmUp.ino b/extras/i2c_warmUp/i2c_warmUp.ino index 256f25548..b9772c437 100644 --- a/extras/i2c_warmUp/i2c_warmUp.ino +++ b/extras/i2c_warmUp/i2c_warmUp.ino @@ -1,7 +1,9 @@ /** ========================================================================= - * @file i2c_warmUp.ino + * @example{lineno} i2c_warmUp.ino * @brief Testing sketch to see how long an attached I2C device takes to * begin to respond to commands. + * + * @m_examplenavigation{page_extra_helper_sketches,} * ======================================================================= */ #include diff --git a/extras/interrupt_counter/interrupt_counter.ino b/extras/interrupt_counter/interrupt_counter.ino index e62419854..8f590f06c 100644 --- a/extras/interrupt_counter/interrupt_counter.ino +++ b/extras/interrupt_counter/interrupt_counter.ino @@ -1,6 +1,8 @@ /** ========================================================================= - * @file interrupt_counter.ino + * @example{lineno} interrupt_counter.ino * @brief Testing sketch counting pin change interrupts. + * + * @m_examplenavigation{page_extra_helper_sketches,} * ======================================================================= */ #include diff --git a/extras/mega_serial_spy/mega_serial_spy.ino b/extras/mega_serial_spy/mega_serial_spy.ino index 5c910c9d6..cbadac2c6 100644 --- a/extras/mega_serial_spy/mega_serial_spy.ino +++ b/extras/mega_serial_spy/mega_serial_spy.ino @@ -1,7 +1,9 @@ /** ========================================================================= - * @file mega_serial_spy.ino + * @example{lineno} mega_serial_spy.ino * @brief Testing sketch to run on an Arduino Mega to print all output from * connected serial ports to the terminal. + * + * @m_examplenavigation{page_extra_helper_sketches,} * ======================================================================= */ #include diff --git a/extras/oneWireSearch/oneWireSearch.ino b/extras/oneWireSearch/oneWireSearch.ino index 718205b83..1c7b363d5 100644 --- a/extras/oneWireSearch/oneWireSearch.ino +++ b/extras/oneWireSearch/oneWireSearch.ino @@ -1,10 +1,10 @@ /** ========================================================================= - * @file oneWireSearch.ino - * @author Rob Tillaart + * @example{lineno} oneWireSearch.ino + * @author Rob Tillaart * VERSION: 0.1.02 * @brief scan for 1-Wire devices + code snippet generator - * DATE: 2015-june-30 - * URL: http://forum.arduino.cc/index.php?topic=333923 + * DATE: 2015-june-30 + * URL: http://forum.arduino.cc/index.php?topic=333923 * * inspired by * http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html @@ -14,6 +14,8 @@ * 0.1.00 initial version * 0.1.01 first published version * 0.1.02 small output changes + * + * @m_examplenavigation{page_extra_helper_sketches,} * ======================================================================= */ #include diff --git a/extras/powerOn/powerOn.ino b/extras/powerOn/powerOn.ino index e6ce8130b..253f70691 100644 --- a/extras/powerOn/powerOn.ino +++ b/extras/powerOn/powerOn.ino @@ -1,7 +1,9 @@ /** ========================================================================= - * @file powerOn.ino + * @example{lineno} powerOn.ino * @brief Testing sketch that simply turns on power to the sensors on the * Mayfly. + * + * @m_examplenavigation{page_extra_helper_sketches,} * ======================================================================= */ #include diff --git a/extras/resetBee/resetBee.ino b/extras/resetBee/resetBee.ino index 275d7aeaa..78da1ac53 100644 --- a/extras/resetBee/resetBee.ino +++ b/extras/resetBee/resetBee.ino @@ -1,6 +1,8 @@ /** ========================================================================= - * @file resetBee.ino + * @example{lineno} resetBee.ino * @brief Testing sketch to fully reset an XBee + * + * @m_examplenavigation{page_extra_helper_sketches,} * ======================================================================= */ #include diff --git a/extras/sdi12_address_change/sdi12_address_change.ino b/extras/sdi12_address_change/sdi12_address_change.ino index 677e17574..7ca735831 100644 --- a/extras/sdi12_address_change/sdi12_address_change.ino +++ b/extras/sdi12_address_change/sdi12_address_change.ino @@ -1,5 +1,5 @@ /** - * @file sdi12_address_change.ino + * @example{lineno} sdi12_address_change.ino * @copyright Stroud Water Research Center * This example is published under the BSD-3 license. * @author Kevin M.Smith @@ -9,6 +9,8 @@ * * The SDI-12 specification is available at: http://www.sdi-12.org/ * The library is available at: https://github.com/EnviroDIY/Arduino-SDI-12 + * + * @m_examplenavigation{page_extra_helper_sketches,} */ diff --git a/src/LoggerBase.h b/src/LoggerBase.h index 87e490260..c5244dce2 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -18,7 +18,9 @@ // Debugging Statement // #define MS_LOGGERBASE_DEBUG -// Set default clock for SAMD21 as DS3231 instead of built-in RTC +/** + * @brief Set default clock for SAMD21 as DS3231 instead of built-in RTC + */ #define MS_SAMD_DS3231 #ifdef MS_LOGGERBASE_DEBUG diff --git a/src/ModSensorInterrupts.h b/src/ModSensorInterrupts.h index dbb89c7cf..e1d7a9a25 100644 --- a/src/ModSensorInterrupts.h +++ b/src/ModSensorInterrupts.h @@ -18,8 +18,16 @@ // #define LIBCALL_ENABLEINTERRUPT // To prevent compiler/linker crashes #include // To handle external and pin change interrupts #else +/** + * @brief This define renames attachInterrupt as enableInterrupt to simplify + * switching between AVR and non-AVR processors. + */ #define enableInterrupt(pin, userFunc, mode) \ attachInterrupt(pin, userFunc, mode) +/** + * @brief This define renames detachInterrupt as disableInterrupt to simplify + * switching between AVR and non-AVR processors. + */ #define disableInterrupt(pin) detachInterrupt(pin) #endif From 3f43dc18b2334e44de7114aaef276dfff06f58f2 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Mon, 16 Sep 2024 13:28:55 -0400 Subject: [PATCH 125/138] Fix extra uart reset on sleep that had been incompletely removed Signed-off-by: Sara Damiano --- src/LoggerBase.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index b5d81fc5f..ab60df4bd 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -947,9 +947,6 @@ void Logger::systemSleep(void) { // Re-enable the processor ADC ADCSRA |= _BV(ADEN); - // restore UART settings - UCSR1B = uart1_old; - // Re-enables interrupts interrupts(); From c11080010ab1d0de874b317e3acdc57719a50e22 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 17 Sep 2024 10:57:53 -0400 Subject: [PATCH 126/138] Fix ifndef warnings Signed-off-by: Sara Damiano --- src/sensors/ApogeeSQ212.h | 2 +- src/sensors/BoschBME280.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sensors/ApogeeSQ212.h b/src/sensors/ApogeeSQ212.h index 0e2e5e773..8bfc96dc6 100644 --- a/src/sensors/ApogeeSQ212.h +++ b/src/sensors/ApogeeSQ212.h @@ -111,7 +111,7 @@ * Defines to set the calibration of the SQ-212 and the address of the ADD. */ /**@{*/ -#ifndef SQ212_CALIBRATION_FACTOR || defined(DOXYGEN) +#if !defined(SQ212_CALIBRATION_FACTOR) || defined(DOXYGEN) /** * @brief The calibration factor between output in volts and PAR * (microeinsteinPerSquareMeterPerSecond) 1 µmol mˉ² sˉ¹ per mV (reciprocal of diff --git a/src/sensors/BoschBME280.h b/src/sensors/BoschBME280.h index ff7a4de98..fd0003d46 100644 --- a/src/sensors/BoschBME280.h +++ b/src/sensors/BoschBME280.h @@ -125,7 +125,7 @@ * calculate altitude by the BME280. */ /**@{*/ -#ifndef SEALEVELPRESSURE_HPA || defined(DOXYGEN) +#if !defined(SEALEVELPRESSURE_HPA) || defined(DOXYGEN) /// The atmospheric pressure at sea level #define SEALEVELPRESSURE_HPA (1013.25) #endif From 8a22e900919462d48a8a8bf1907576db62cd34e4 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 17 Sep 2024 10:58:11 -0400 Subject: [PATCH 127/138] Bump sdi12 Signed-off-by: Sara Damiano --- continuous_integration/dependencies.json | 4 ++-- library.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/continuous_integration/dependencies.json b/continuous_integration/dependencies.json index 5e8ca2db8..dd3becbe9 100644 --- a/continuous_integration/dependencies.json +++ b/continuous_integration/dependencies.json @@ -246,7 +246,7 @@ "name": "SDI-12", "owner": "envirodiy", "library id": "1486", - "version": "~2.1.4", + "version": "~2.2.0", "url": "https://github.com/EnviroDIY/Arduino-SDI-12", "note": "EnviroDIY SDI-12 Library for Arduino", "author_notes": [ @@ -335,4 +335,4 @@ "platforms": "atmelavr, atmelsam" } ] -} \ No newline at end of file +} diff --git a/library.json b/library.json index 3bb66c8bb..14714c136 100644 --- a/library.json +++ b/library.json @@ -268,7 +268,7 @@ "name": "SDI-12", "owner": "envirodiy", "library id": "1486", - "version": "~2.1.4", + "version": "~2.2.0", "url": "https://github.com/EnviroDIY/Arduino-SDI-12", "note": "EnviroDIY SDI-12 Library for Arduino", "author_notes": [ From 2bcb001729ff52b66559d08a9762e849dbc2a36a Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 17 Sep 2024 12:04:57 -0400 Subject: [PATCH 128/138] Fix for Zero Signed-off-by: Sara Damiano --- continuous_integration/platformio.ini | 1 + src/ModSensorInterrupts.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/continuous_integration/platformio.ini b/continuous_integration/platformio.ini index 6b56d0d53..480331f56 100644 --- a/continuous_integration/platformio.ini +++ b/continuous_integration/platformio.ini @@ -22,6 +22,7 @@ lib_ignore = Adafruit TouchScreen Adafruit ILI9341 build_flags = + -Wall -Wextra -D SDI12_EXTERNAL_PCINT -D NEOSWSERIAL_EXTERNAL_PCINT diff --git a/src/ModSensorInterrupts.h b/src/ModSensorInterrupts.h index e1d7a9a25..808475155 100644 --- a/src/ModSensorInterrupts.h +++ b/src/ModSensorInterrupts.h @@ -14,6 +14,8 @@ #ifndef SRC_MODSENSORINTERRUPTS_H_ #define SRC_MODSENSORINTERRUPTS_H_ +#include + #if defined(__AVR__) // #define LIBCALL_ENABLEINTERRUPT // To prevent compiler/linker crashes #include // To handle external and pin change interrupts From 88eb8d6d3f7ffe4153e92ea7550a2b79f9473ae7 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 18 Sep 2024 11:33:40 -0400 Subject: [PATCH 129/138] defined checks consistently as fxns Signed-off-by: Sara Damiano --- .gitignore | 3 + examples/data_saving/data_saving.ino | 12 +- examples/logging_to_MMW/logging_to_MMW.ino | 6 +- examples/menu_a_la_carte/menu_a_la_carte.ino | 266 +++++++++---------- src/LoggerBase.cpp | 40 +-- src/LoggerBase.h | 4 +- src/ModSensorDebugger.h | 8 +- src/modems/LoggerModemMacros.h | 8 +- src/publishers/ThingSpeakPublisher.cpp | 2 +- src/sensors/AOSongAM2315.h | 2 +- src/sensors/AnalogElecConductivity.cpp | 2 +- src/sensors/AnalogElecConductivity.h | 14 +- src/sensors/BoschBMP3xx.h | 2 +- src/sensors/EverlightALSPT19.cpp | 2 +- src/sensors/EverlightALSPT19.h | 10 +- src/sensors/PaleoTerraRedox.cpp | 8 +- src/sensors/PaleoTerraRedox.h | 4 +- src/sensors/RainCounterI2C.cpp | 8 +- src/sensors/RainCounterI2C.h | 2 +- 19 files changed, 203 insertions(+), 200 deletions(-) diff --git a/.gitignore b/.gitignore index f78bb1753..bca6ee90c 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,6 @@ generateKeywords.bat update_path.bat pio_common_libdeps.ini ex_one_offs/* +output_deep.txt +output_deep+.txt +envDump.txt diff --git a/examples/data_saving/data_saving.ino b/examples/data_saving/data_saving.ino index e6f445415..a540cd5e3 100644 --- a/examples/data_saving/data_saving.ino +++ b/examples/data_saving/data_saving.ino @@ -47,7 +47,7 @@ // peripherals as possible. In some cases (ie, modbus communication) many // sensors can share the same serial port. -#if not defined ARDUINO_ARCH_SAMD && not defined ATMEGA2560 // For AVR boards +#if !defined(ARDUINO_ARCH_SAMD) && !defined(ATMEGA2560) // For AVR boards // Unfortunately, most AVR boards have only one or two hardware serial ports, // so we'll set up three types of extra software serial ports to use @@ -61,7 +61,7 @@ AltSoftSerial altSoftSerial; #endif // End software serial for avr boards -#if defined ARDUINO_ARCH_SAMD +#if defined(ARDUINO_ARCH_SAMD) #include // Needed for SAMD pinPeripheral() function #ifndef ENABLE_SERIAL2 @@ -395,7 +395,7 @@ void setup() { // Wait for USB connection to be established by PC // NOTE: Only use this when debugging - if not connected to a PC, this // could prevent the script from starting -#if defined SERIAL_PORT_USBVIRTUAL +#if defined(SERIAL_PORT_USBVIRTUAL) while (!SERIAL_PORT_USBVIRTUAL && (millis() < 10000)) { // wait } @@ -423,7 +423,7 @@ void setup() { // Assign pins SERCOM functionality for SAMD boards // NOTE: This must happen *after* the various serial.begin statements -#if defined ARDUINO_ARCH_SAMD +#if defined(ARDUINO_ARCH_SAMD) #ifndef ENABLE_SERIAL2 pinPeripheral(10, PIO_SERCOM); // Serial2 Tx/Dout = SERCOM1 Pad #2 pinPeripheral(11, PIO_SERCOM); // Serial2 Rx/Din = SERCOM1 Pad #0 @@ -544,7 +544,7 @@ void loop() { // we will explicitly start and end the serial connection in the loop. modbusSerial.end(); -#if defined AltSoftSerial_h +#if defined(AltSoftSerial_h) // Explicitly set the pin modes for the AltSoftSerial pins to make sure // they're low pinMode(5, OUTPUT); // On a Mayfly, pin D5 is the AltSoftSerial Tx pin @@ -553,7 +553,7 @@ void loop() { digitalWrite(6, LOW); #endif -#if defined ARDUINO_SAMD_ZERO +#if defined(ARDUINO_SAMD_ZERO) digitalWrite(10, LOW); digitalWrite(11, LOW); #endif diff --git a/examples/logging_to_MMW/logging_to_MMW.ino b/examples/logging_to_MMW/logging_to_MMW.ino index eece23667..b4791b41f 100644 --- a/examples/logging_to_MMW/logging_to_MMW.ino +++ b/examples/logging_to_MMW/logging_to_MMW.ino @@ -253,7 +253,7 @@ void setup() { // Wait for USB connection to be established by PC // NOTE: Only use this when debugging - if not connected to a PC, this // could prevent the script from starting -#if defined SERIAL_PORT_USBVIRTUAL +#if defined(SERIAL_PORT_USBVIRTUAL) while (!SERIAL_PORT_USBVIRTUAL && (millis() < 10000)) { // wait } @@ -276,11 +276,11 @@ void setup() { Serial.println(); // Allow interrupts for software serial -#if defined SoftwareSerial_ExtInts_h +#if defined(SoftwareSerial_ExtInts_h) enableInterrupt(softSerialRx, SoftwareSerial_ExtInts::handle_interrupt, CHANGE); #endif -#if defined NeoSWSerial_h +#if defined(NeoSWSerial_h) enableInterrupt(neoSSerial1Rx, neoSSerial1ISR, CHANGE); #endif diff --git a/examples/menu_a_la_carte/menu_a_la_carte.ino b/examples/menu_a_la_carte/menu_a_la_carte.ino index fb2c483e2..5720f93fe 100644 --- a/examples/menu_a_la_carte/menu_a_la_carte.ino +++ b/examples/menu_a_la_carte/menu_a_la_carte.ino @@ -115,11 +115,11 @@ const int8_t softwareSDA = 5; const int8_t softwareSCL = 4; SoftwareWire softI2C(softwareSDA, softwareSCL); /** End [softwarewire] */ -#endif // #if defined MS_PALEOTERRA_SOFTWAREWIRE ... +#endif // #if defined(MS_PALEOTERRA_SOFTWAREWIRE) ... #endif // End software serial for avr boards -#if defined ARDUINO_ARCH_SAMD +#if defined(ARDUINO_ARCH_SAMD) /** Start [serial_ports_SAMD] */ // The SAMD21 has 6 "SERCOM" ports, any of which can be used for UART // communication. The "core" code for most boards defines one or more UART @@ -213,9 +213,9 @@ void SERCOM2_Handler() { // SoftwareSerial **WILL NOT** work for modbus! #ifdef BUILD_TEST_ALTSOFTSERIAL #define modbusSerial altSoftSerial // For AltSoftSerial -#elif defined BUILD_TEST_NEOSWSERIAL +#elif defined(BUILD_TEST_NEOSWSERIAL) #define modbusSerial neoSSerial1 // For Neo software serial -#elif defined BUILD_TEST_SOFTSERIAL +#elif defined(BUILD_TEST_SOFTSERIAL) #define modbusSerial softSerial1 // For software serial #else #define modbusSerial Serial1 // Hardware serial @@ -227,9 +227,9 @@ void SERCOM2_Handler() { // string repeatedly, almost any software serial port will do for it. #ifdef BUILD_TEST_ALTSOFTSERIAL #define sonarSerial altSoftSerial // For AltSoftSerial -#elif defined BUILD_TEST_NEOSWSERIAL +#elif defined(BUILD_TEST_NEOSWSERIAL) #define sonarSerial neoSSerial1 // For Neo software serial -#elif defined BUILD_TEST_SOFTSERIAL +#elif defined(BUILD_TEST_SOFTSERIAL) #define sonarSerial softSerial1 // For software serial #else #define sonarSerial Serial1 // Hardware serial @@ -275,7 +275,7 @@ const int8_t sensorPowerPin = 22; // MCU pin controlling main sensor power // Delete the sections you are not using! // ========================================================================== -#if defined BUILD_MODEM_DIGI_XBEE_CELLULAR_TRANSPARENT +#if defined(BUILD_MODEM_DIGI_XBEE_CELLULAR_TRANSPARENT) /** Start [digi_xbee_cellular_transparent] */ // For any Digi Cellular XBee's // NOTE: The u-blox based Digi XBee's (3G global and LTE-M global) can be used @@ -316,7 +316,7 @@ DigiXBeeCellularTransparent modem = modemXBCT; // ========================================================================== -#elif defined BUILD_MODEM_DIGI_XBEE_LTE_BYPASS +#elif defined(BUILD_MODEM_DIGI_XBEE_LTE_BYPASS) /** Start [digi_xbee_lte_bypass] */ // For the u-blox SARA R410M based Digi LTE-M XBee3 // NOTE: According to the manual, this should be less stable than transparent @@ -353,7 +353,7 @@ DigiXBeeLTEBypass modem = modemXBLTEB; // ========================================================================== -#elif defined BUILD_MODEM_DIGI_XBEE_3G_BYPASS +#elif defined(BUILD_MODEM_DIGI_XBEE_3G_BYPASS) /** Start [digi_xbee_3g_bypass] */ // For the u-blox SARA U201 based Digi 3G XBee with 2G fallback // NOTE: According to the manual, this should be less stable than transparent @@ -390,7 +390,7 @@ DigiXBee3GBypass modem = modemXB3GB; // ========================================================================== -#elif defined BUILD_MODEM_DIGI_XBEE_WIFI +#elif defined(BUILD_MODEM_DIGI_XBEE_WIFI) /** Start [digi_xbee_wifi] */ // For the Digi Wifi XBee (S6B) #include @@ -426,7 +426,7 @@ DigiXBeeWifi modem = modemXBWF; // ========================================================================== -#elif defined BUILD_MODEM_ESPRESSIF_ESP8266 +#elif defined(BUILD_MODEM_ESPRESSIF_ESP8266) /** Start [espressif_esp8266] */ // For almost anything based on the Espressif ESP8266 using the // AT command firmware @@ -461,7 +461,7 @@ EspressifESP8266 modem = modemESP; // ========================================================================== -#elif defined BUILD_MODEM_ESPRESSIF_ESP32 +#elif defined(BUILD_MODEM_ESPRESSIF_ESP32) /** Start [espressif_esp32] */ // For almost anything based on the Espressif ESP8266 using the // AT command firmware @@ -496,7 +496,7 @@ EspressifESP32 modem = modemESP; // ========================================================================== -#elif defined BUILD_MODEM_QUECTEL_BG96 +#elif defined(BUILD_MODEM_QUECTEL_BG96) /** Start [quectel_bg96] */ // For the Dragino, Nimbelink or other boards based on the Quectel BG96 #include @@ -530,7 +530,7 @@ QuectelBG96 modem = modemBG96; // ========================================================================== -#elif defined BUILD_MODEM_SEQUANS_MONARCH +#elif defined(BUILD_MODEM_SEQUANS_MONARCH) /** Start [sequans_monarch] */ // For the Nimbelink LTE-M Verizon/Sequans or other boards based on the Sequans // Monarch series @@ -565,7 +565,7 @@ SequansMonarch modem = modemSVZM; // ========================================================================== -#elif defined BUILD_MODEM_SIM_COM_SIM800 +#elif defined(BUILD_MODEM_SIM_COM_SIM800) /** Start [sim_com_sim800] */ // For almost anything based on the SIMCom SIM800 EXCEPT the Sodaq 2GBee R6 and // higher @@ -597,7 +597,7 @@ SIMComSIM800 modem = modemS800; // ========================================================================== -#elif defined BUILD_MODEM_SIM_COM_SIM7000 +#elif defined(BUILD_MODEM_SIM_COM_SIM7000) /** Start [sim_com_sim7000] */ // For almost anything based on the SIMCom SIM7000 #include @@ -627,7 +627,7 @@ SIMComSIM7000 modem = modem7000; // ========================================================================== -#elif defined BUILD_MODEM_SIM_COM_SIM7080 +#elif defined(BUILD_MODEM_SIM_COM_SIM7080) /** Start [sim_com_sim7080] */ // For almost anything based on the SIMCom SIM7080G #include @@ -658,7 +658,7 @@ SIMComSIM7080 modem = modem7080; // ========================================================================== -#elif defined BUILD_MODEM_SODAQ_2G_BEE_R6 +#elif defined(BUILD_MODEM_SODAQ_2G_BEE_R6) /** Start [sodaq_2g_bee_r6] */ // For the Sodaq 2GBee R6 and R7 based on the SIMCom SIM800 // NOTE: The Sodaq GPRSBee doesn't expose the SIM800's reset pin @@ -689,7 +689,7 @@ Sodaq2GBeeR6 modem = modem2GB; // ========================================================================== -#elif defined BUILD_MODEM_SODAQ_UBEE_R410M +#elif defined(BUILD_MODEM_SODAQ_UBEE_R410M) /** Start [sodaq_ubee_r410m] */ // For the Sodaq UBee based on the 4G LTE-M u-blox SARA R410M #include @@ -727,7 +727,7 @@ SodaqUBeeR410M modem = modemR410; // ========================================================================== -#elif defined BUILD_MODEM_SODAQ_UBEE_U201 +#elif defined(BUILD_MODEM_SODAQ_UBEE_U201) /** Start [sodaq_ubee_u201] */ // For the Sodaq UBee based on the 3G u-blox SARA U201 #include @@ -815,7 +815,7 @@ Variable* ds3231Temp = #endif -#if defined BUILD_SENSOR_AO_SONG_AM2315 +#if defined(BUILD_SENSOR_AO_SONG_AM2315) // ========================================================================== // AOSong AM2315 Digital Humidity and Temperature Sensor // ========================================================================== @@ -837,7 +837,7 @@ Variable* am2315Temp = #endif -#if defined BUILD_SENSOR_AO_SONG_DHT +#if defined(BUILD_SENSOR_AO_SONG_DHT) // ========================================================================== // AOSong DHT 11/21 (AM2301)/22 (AM2302) Digital Humidity and Temperature // ========================================================================== @@ -864,7 +864,7 @@ Variable* dhtHI = new AOSongDHT_HI(&dht, #endif -#if defined BUILD_SENSOR_APOGEE_SQ212 +#if defined(BUILD_SENSOR_APOGEE_SQ212) // ========================================================================== // Apogee SQ-212 Photosynthetically Active Radiation (PAR) Sensor // ========================================================================== @@ -888,7 +888,7 @@ Variable* sq212voltage = #endif -#if defined BUILD_SENSOR_ATLAS_SCIENTIFIC_CO2 +#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_CO2) // ========================================================================== // Atlas Scientific EZO-CO2 Embedded NDIR Carbon Dioxide Sensor // ========================================================================== @@ -915,7 +915,7 @@ Variable* atlasCO2Temp = new AtlasScientificCO2_Temp( #endif -#if defined BUILD_SENSOR_ATLAS_SCIENTIFIC_DO +#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_DO) // ========================================================================== // Atlas Scientific EZO-DO Dissolved Oxygen Sensor // ========================================================================== @@ -942,7 +942,7 @@ Variable* atlasDOpct = new AtlasScientificDO_DOpct( #endif -#if defined BUILD_SENSOR_ATLAS_SCIENTIFIC_ORP +#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_ORP) // ========================================================================== // Atlas Scientific EZO-ORP Oxidation/Reduction Potential Sensor // ========================================================================== @@ -967,7 +967,7 @@ Variable* atlasORPot = new AtlasScientificORP_Potential( #endif -#if defined BUILD_SENSOR_ATLAS_SCIENTIFIC_PH +#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_PH) // ========================================================================== // Atlas Scientific EZO-pH Sensor // ========================================================================== @@ -1018,7 +1018,7 @@ Variable* atlasTemp = new AtlasScientificRTD_Temp( #endif -#if defined BUILD_SENSOR_ATLAS_SCIENTIFIC_EC +#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_EC) // ========================================================================== // Atlas Scientific EZO-EC Conductivity Sensor // ========================================================================== @@ -1090,7 +1090,7 @@ Variable* atlasSpCond = #endif -#if defined BUILD_SENSOR_BOSCH_BME280 +#if defined(BUILD_SENSOR_BOSCH_BME280) // ========================================================================== // Bosch BME280 Environmental Sensor // ========================================================================== @@ -1119,7 +1119,7 @@ Variable* bme280Alt = #endif -#if defined BUILD_SENSOR_BOSCH_BMP3XX +#if defined(BUILD_SENSOR_BOSCH_BMP3XX) // ========================================================================== // Bosch BMP 3xx Barometric Pressure Sensor // ========================================================================== @@ -1152,7 +1152,7 @@ Variable* bmp3xxAlt = #endif -#if defined BUILD_SENSOR_CAMPBELL_CLARI_VUE10 +#if defined(BUILD_SENSOR_CAMPBELL_CLARI_VUE10) // ========================================================================== // Campbell ClariVUE Turbidity Sensor // ========================================================================== @@ -1180,7 +1180,7 @@ Variable* clarivueError = new CampbellClariVUE10_ErrorCode( #endif -#if defined BUILD_SENSOR_CAMPBELL_OBS3 +#if defined(BUILD_SENSOR_CAMPBELL_OBS3) // ========================================================================== // Campbell OBS 3 / OBS 3+ Analog Turbidity Sensor // ========================================================================== @@ -1229,7 +1229,7 @@ Variable* obs3VoltHigh = new CampbellOBS3_Voltage( /** End [campbell_obs3] */ #endif -#if defined BUILD_SENSOR_CAMPBELL_RAIN_VUE10 +#if defined(BUILD_SENSOR_CAMPBELL_RAIN_VUE10) // ========================================================================== // Campbell RainVUE Precipitation Sensor // ========================================================================== @@ -1259,7 +1259,7 @@ Variable* rainvueRainRateMax = new CampbellRainVUE10_RainRateMax( #endif -#if defined BUILD_SENSOR_DECAGON_CTD +#if defined(BUILD_SENSOR_DECAGON_CTD) // ========================================================================== // Decagon CTD-10 Conductivity, Temperature, and Depth Sensor // ========================================================================== @@ -1286,7 +1286,7 @@ Variable* ctdDepth = #endif -#if defined BUILD_SENSOR_DECAGON_ES2 +#if defined(BUILD_SENSOR_DECAGON_ES2) // ========================================================================== // Decagon ES2 Conductivity and Temperature Sensor // ========================================================================== @@ -1311,7 +1311,7 @@ Variable* es2Temp = new DecagonES2_Temp(&es2, #endif -#if defined BUILD_SENSOR_EVERLIGHT_ALSPT19 +#if defined(BUILD_SENSOR_EVERLIGHT_ALSPT19) // ========================================================================== // Everlight ALS-PT19 Ambient Light Sensor // ========================================================================== @@ -1343,7 +1343,7 @@ Variable* alsPt19Lux = new EverlightALSPT19_Illuminance( #endif -#if defined BUILD_SENSOR_TIADS1X15 +#if defined(BUILD_SENSOR_TIADS1X15) // ========================================================================== // External Voltage via TI ADS1115 // ========================================================================== @@ -1368,7 +1368,7 @@ Variable* ads1x15Volt = #endif -#if defined BUILD_SENSOR_FREESCALE_MPL115A2 +#if defined(BUILD_SENSOR_FREESCALE_MPL115A2) // ========================================================================== // Freescale Semiconductor MPL115A2 Barometer // ========================================================================== @@ -1390,7 +1390,7 @@ Variable* mplTemp = new FreescaleMPL115A2_Temp( /** End [freescale_mpl115a2] */ #endif -#if defined BUILD_SENSOR_GRO_POINT_GPLP8 +#if defined(BUILD_SENSOR_GRO_POINT_GPLP8) // ========================================================================== // GroPoint Profile GPLP-8 Soil Moisture and Temperature Sensor // ========================================================================== @@ -1463,7 +1463,7 @@ Variable* gplp8Temp13 = new GroPointGPLP8_Temp( #endif -#if defined BUILD_SENSOR_IN_SITU_RDO +#if defined(BUILD_SENSOR_IN_SITU_RDO) // ========================================================================== // In-Situ RDO PRO-X Rugged Dissolved Oxygen Probe // ========================================================================== @@ -1493,7 +1493,7 @@ Variable* rdoO2pp = #endif -#if defined BUILD_SENSOR_IN_SITU_TROLL_SDI12A +#if defined(BUILD_SENSOR_IN_SITU_TROLL_SDI12A) // ========================================================================== // In-Situ Aqua/Level TROLL Pressure, Temperature, and Depth Sensor // ========================================================================== @@ -1523,7 +1523,7 @@ Variable* trollDepth = new InSituTrollSdi12a_Depth( #endif -#if defined BUILD_SENSOR_KELLER_ACCULEVEL +#if defined(BUILD_SENSOR_KELLER_ACCULEVEL) // ========================================================================== // Keller Acculevel High Accuracy Submersible Level Transmitter // ========================================================================== @@ -1557,7 +1557,7 @@ Variable* acculevHeight = new KellerAcculevel_Height( #endif -#if defined BUILD_SENSOR_KELLER_NANOLEVEL +#if defined(BUILD_SENSOR_KELLER_NANOLEVEL) // ========================================================================== // Keller Nanolevel High Accuracy Submersible Level Transmitter // ========================================================================== @@ -1591,7 +1591,7 @@ Variable* nanolevHeight = new KellerNanolevel_Height( #endif -#if defined BUILD_SENSOR_MAX_BOTIX_SONAR +#if defined(BUILD_SENSOR_MAX_BOTIX_SONAR) // ========================================================================== // Maxbotix HRXL Ultrasonic Range Finder // ========================================================================== @@ -1653,7 +1653,7 @@ Variable* ds18Temp = new MaximDS18_Temp(&ds18, #endif -#if defined BUILD_SENSOR_MEA_SPEC_MS5803 +#if defined(BUILD_SENSOR_MEA_SPEC_MS5803) // ========================================================================== // Measurement Specialties MS5803-14BA pressure sensor // ========================================================================== @@ -1681,7 +1681,7 @@ Variable* ms5803Temp = #endif -#if defined BUILD_SENSOR_DECAGON_5TM +#if defined(BUILD_SENSOR_DECAGON_5TM) // ========================================================================== // Meter ECH2O Soil Moisture Sensor // ========================================================================== @@ -1708,7 +1708,7 @@ Variable* fivetmTemp = #endif -#if defined BUILD_SENSOR_METER_HYDROS21 +#if defined(BUILD_SENSOR_METER_HYDROS21) // ========================================================================== // Meter Hydros 21 Conductivity, Temperature, and Depth Sensor // ========================================================================== @@ -1737,7 +1737,7 @@ Variable* hydros21Depth = #endif -#if defined BUILD_SENSOR_METER_TEROS11 +#if defined(BUILD_SENSOR_METER_TEROS11) // ========================================================================== // Meter Teros 11 Soil Moisture Sensor // ========================================================================== @@ -1768,7 +1768,7 @@ Variable* teros11Count = #endif -#if defined BUILD_SENSOR_PALEO_TERRA_REDOX +#if defined(BUILD_SENSOR_PALEO_TERRA_REDOX) // ========================================================================== // PaleoTerra Redox Sensors // ========================================================================== @@ -1795,7 +1795,7 @@ Variable* ptVolt = new PaleoTerraRedox_Voltage( #endif -#if defined BUILD_SENSOR_RAIN_COUNTER_I2C +#if defined(BUILD_SENSOR_RAIN_COUNTER_I2C) // ========================================================================== // External I2C Rain Tipping Bucket Counter // ========================================================================== @@ -1824,7 +1824,7 @@ Variable* tbi2cDepth = #endif -#if defined BUILD_SENSOR_SENSIRION_SHT4X +#if defined(BUILD_SENSOR_SENSIRION_SHT4X) // ========================================================================== // Sensirion SHT4X Digital Humidity and Temperature Sensor // ========================================================================== @@ -1847,7 +1847,7 @@ Variable* sht4xTemp = #endif -#if defined BUILD_SENSOR_TALLY_COUNTER_I2C +#if defined(BUILD_SENSOR_TALLY_COUNTER_I2C) // ========================================================================== // Tally I2C Event Counter for rain or wind reed-switch sensors // ========================================================================== @@ -1880,7 +1880,7 @@ Variable* tallyEvents = new TallyCounterI2C_Events( #endif -#if defined BUILD_SENSOR_TI_INA219 +#if defined(BUILD_SENSOR_TI_INA219) // ========================================================================== // TI INA219 High Side Current/Voltage Sensor (Current mA, Voltage, Power) // ========================================================================== @@ -1908,7 +1908,7 @@ Variable* inaPower = new TIINA219_Power(&ina219, #endif -#if defined BUILD_SENSOR_TURNER_CYCLOPS +#if defined(BUILD_SENSOR_TURNER_CYCLOPS) // ========================================================================== // Turner Cyclops-7F Submersible Fluorometer // ========================================================================== @@ -1970,7 +1970,7 @@ Variable* cyclopsRedChloro = new TurnerCyclops_RedChlorophyll( #endif -#if defined BUILD_SENSOR_ANALOG_ELEC_CONDUCTIVITY +#if defined(BUILD_SENSOR_ANALOG_ELEC_CONDUCTIVITY) // ========================================================================== // Analog Electrical Conductivity using the Processor's Analog Pins // ========================================================================== @@ -2031,7 +2031,7 @@ Variable* analogEc_spcond = new Variable( #endif -#if defined BUILD_SENSOR_VEGA_PULS21 +#if defined(BUILD_SENSOR_VEGA_PULS21) // ========================================================================== // VEGA PULS 21 Radar Sensor // ========================================================================== @@ -2064,7 +2064,7 @@ Variable* VegaPulsError = #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y504 +#if defined(BUILD_SENSOR_YOSEMITECH_Y504) // ========================================================================== // Yosemitech Y504 Dissolved Oxygen Sensor // ========================================================================== @@ -2099,7 +2099,7 @@ Variable* y504Temp = #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y510 +#if defined(BUILD_SENSOR_YOSEMITECH_Y510) // ========================================================================== // Yosemitech Y510 Turbidity Sensor // ========================================================================== @@ -2131,7 +2131,7 @@ Variable* y510Temp = #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y511 +#if defined(BUILD_SENSOR_YOSEMITECH_Y511) // ========================================================================== // Yosemitech Y511 Turbidity Sensor with Wiper // ========================================================================== @@ -2163,7 +2163,7 @@ Variable* y511Temp = #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y514 +#if defined(BUILD_SENSOR_YOSEMITECH_Y514) // ========================================================================== // Yosemitech Y514 Chlorophyll Sensor // ========================================================================== @@ -2196,7 +2196,7 @@ Variable* y514Temp = #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y520 +#if defined(BUILD_SENSOR_YOSEMITECH_Y520) // ========================================================================== // Yosemitech Y520 Conductivity Sensor // ========================================================================== @@ -2228,7 +2228,7 @@ Variable* y520Temp = #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y532 +#if defined(BUILD_SENSOR_YOSEMITECH_Y532) // ========================================================================== // Yosemitech Y532 pH // ========================================================================== @@ -2262,7 +2262,7 @@ Variable* y532Temp = #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y533 +#if defined(BUILD_SENSOR_YOSEMITECH_Y533) // ========================================================================== // Yosemitech Y533 Oxidation Reduction Potential (ORP) // ========================================================================== @@ -2293,7 +2293,7 @@ Variable* y533Temp = #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y551 +#if defined(BUILD_SENSOR_YOSEMITECH_Y551) // ========================================================================== // Yosemitech Y551 COD Sensor with Wiper // ========================================================================== @@ -2327,7 +2327,7 @@ Variable* y551Temp = #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y560 +#if defined(BUILD_SENSOR_YOSEMITECH_Y560) // ========================================================================== // Yosemitech Y560 Ammonium Probe with Wiper // ========================================================================== @@ -2363,7 +2363,7 @@ Variable* y560Temp = #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y700 +#if defined(BUILD_SENSOR_YOSEMITECH_Y700) // ========================================================================== // Yosemitech Y700 Pressure Sensor // ========================================================================== @@ -2395,7 +2395,7 @@ Variable* y700Temp = #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y4000 +#if defined(BUILD_SENSOR_YOSEMITECH_Y4000) // ========================================================================== // Yosemitech Y4000 Multiparameter Sonde (DOmgL, Turbidity, Cond, pH, Temp, // ORP, Chlorophyll, BGA) @@ -2440,7 +2440,7 @@ Variable* y4000BGA = #endif -#if defined BUILD_SENSOR_ZEBRA_TECH_D_OPTO +#if defined(BUILD_SENSOR_ZEBRA_TECH_D_OPTO) // ========================================================================== // Zebra Tech D-Opto Dissolved Oxygen Sensor // ========================================================================== @@ -2506,7 +2506,7 @@ Variable* calculatedVar = new Variable( /** End [calculated_variables] */ -#if defined BUILD_TEST_CREATE_IN_ARRAY +#if defined(BUILD_TEST_CREATE_IN_ARRAY) // ========================================================================== // Creating the Variable Array[s] and Filling with Variable Objects // NOTE: This shows three different ways of creating the same variable array @@ -2539,7 +2539,7 @@ VariableArray varArray(variableCount, variableList); // ========================================================================== -#elif defined BUILD_TEST_SEPARATE_UUIDS +#elif defined(BUILD_TEST_SEPARATE_UUIDS) /** Start [variables_separate_uuids] */ // Version 2: Create two separate arrays, on for the variables and a separate // one for the UUID's, then give both as input to the variable array @@ -2586,93 +2586,93 @@ Variable* variableList[] = { #if defined(ARDUINO_ARCH_AVR) || defined(MS_SAMD_DS3231) ds3231Temp, #endif -#if defined BUILD_SENSOR_AO_SONG_AM2315 +#if defined(BUILD_SENSOR_AO_SONG_AM2315) am2315Humid, am2315Temp, #endif -#if defined BUILD_SENSOR_AO_SONG_DHT +#if defined(BUILD_SENSOR_AO_SONG_DHT) dhtHumid, dhtTemp, dhtHI, #endif -#if defined BUILD_SENSOR_APOGEE_SQ212 +#if defined(BUILD_SENSOR_APOGEE_SQ212) sq212PAR, sq212voltage, #endif -#if defined BUILD_SENSOR_ATLAS_SCIENTIFIC_CO2 +#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_CO2) atlasCO2CO2, atlasCO2Temp, #endif -#if defined BUILD_SENSOR_ATLAS_SCIENTIFIC_DO +#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_DO) atlasDOconc, atlasDOpct, #endif -#if defined BUILD_SENSOR_ATLAS_SCIENTIFIC_ORP +#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_ORP) atlasORPot, #endif -#if defined BUILD_SENSOR_ATLAS_SCIENTIFIC_PH +#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_PH) atlaspHpH, #endif -#if defined BUILD_SENSOR_ATLAS_SCIENTIFIC_RTD +#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_RTD) atlasTemp, #endif -#if defined BUILD_SENSOR_ATLAS_SCIENTIFIC_EC +#if defined(BUILD_SENSOR_ATLAS_SCIENTIFIC_EC) atlasCond, atlasTDS, atlasSal, atlasGrav, atlasSpCond, #endif -#if defined BUILD_SENSOR_BOSCH_BME280 +#if defined(BUILD_SENSOR_BOSCH_BME280) bme280Temp, bme280Humid, bme280Press, bme280Alt, #endif -#if defined BUILD_SENSOR_BOSCH_BMP3XX +#if defined(BUILD_SENSOR_BOSCH_BMP3XX) bmp3xxTemp, bmp3xxPress, bmp3xxAlt, #endif -#if defined BUILD_SENSOR_CAMPBELL_CLARI_VUE10 +#if defined(BUILD_SENSOR_CAMPBELL_CLARI_VUE10) clarivueTurbidity, clarivueTemp, clarivueError, #endif -#if defined BUILD_SENSOR_CAMPBELL_OBS3 +#if defined(BUILD_SENSOR_CAMPBELL_OBS3) obs3TurbLow, obs3VoltLow, obs3TurbHigh, obs3VoltHigh, #endif -#if defined BUILD_SENSOR_CAMPBELL_RAIN_VUE10 +#if defined(BUILD_SENSOR_CAMPBELL_RAIN_VUE10) rainvuePrecipitation, rainvueTips, rainvueRainRateAve, rainvueRainRateMax, #endif -#if defined BUILD_SENSOR_DECAGON_CTD +#if defined(BUILD_SENSOR_DECAGON_CTD) ctdCond, ctdTemp, ctdDepth, #endif -#if defined BUILD_SENSOR_DECAGON_ES2 +#if defined(BUILD_SENSOR_DECAGON_ES2) es2Cond, es2Temp, #endif -#if defined BUILD_SENSOR_EVERLIGHT_ALSPT19 +#if defined(BUILD_SENSOR_EVERLIGHT_ALSPT19) alsPt19Volt, alsPt19Current, alsPt19Lux, #endif -#if defined BUILD_SENSOR_TIADS1X15 +#if defined(BUILD_SENSOR_TIADS1X15) ads1x15Volt, #endif -#if defined BUILD_SENSOR_FREESCALE_MPL115A2 +#if defined(BUILD_SENSOR_FREESCALE_MPL115A2) mplTemp, mplPress, #endif -#if defined BUILD_SENSOR_GRO_POINT_GPLP8 +#if defined(BUILD_SENSOR_GRO_POINT_GPLP8) gplp8Moist1, gplp8Moist2, gplp8Moist3, @@ -2695,73 +2695,73 @@ Variable* variableList[] = { gplp8Temp12, gplp8Temp13, #endif -#if defined BUILD_SENSOR_IN_SITU_RDO +#if defined(BUILD_SENSOR_IN_SITU_RDO) rdoTemp, rdoDOpct, rdoDOmgL, rdoO2pp, #endif -#if defined BUILD_SENSOR_IN_SITU_TROLL_SDI12A +#if defined(BUILD_SENSOR_IN_SITU_TROLL_SDI12A) trollPressure, trollTemp, trollDepth, #endif -#if defined BUILD_SENSOR_KELLER_ACCULEVEL +#if defined(BUILD_SENSOR_KELLER_ACCULEVEL) acculevPress, acculevTemp, acculevHeight, #endif -#if defined BUILD_SENSOR_KELLER_NANOLEVEL +#if defined(BUILD_SENSOR_KELLER_NANOLEVEL) nanolevPress, nanolevTemp, nanolevHeight, #endif -#if defined BUILD_SENSOR_MAX_BOTIX_SONAR +#if defined(BUILD_SENSOR_MAX_BOTIX_SONAR) sonar1Range, #endif -#if defined BUILD_SENSOR_MAXIM_DS18 +#if defined(BUILD_SENSOR_MAXIM_DS18) ds18Temp, #endif -#if defined BUILD_SENSOR_MEA_SPEC_MS5803 +#if defined(BUILD_SENSOR_MEA_SPEC_MS5803) ms5803Temp, ms5803Press, #endif -#if defined BUILD_SENSOR_DECAGON_5TM +#if defined(BUILD_SENSOR_DECAGON_5TM) fivetmEa, fivetmVWC, fivetmTemp, #endif -#if defined BUILD_SENSOR_METER_HYDROS21 +#if defined(BUILD_SENSOR_METER_HYDROS21) hydros21Cond, hydros21Temp, hydros21Depth, #endif -#if defined BUILD_SENSOR_METER_TEROS11 +#if defined(BUILD_SENSOR_METER_TEROS11) teros11Ea, teros11Temp, teros11VWC, teros11Count, #endif -#if defined BUILD_SENSOR_PALEO_TERRA_REDOX +#if defined(BUILD_SENSOR_PALEO_TERRA_REDOX) ptVolt, #endif -#if defined BUILD_SENSOR_RAIN_COUNTER_I2C +#if defined(BUILD_SENSOR_RAIN_COUNTER_I2C) tbi2cTips, tbi2cDepth, #endif -#if defined BUILD_SENSOR_SENSIRION_SHT4X +#if defined(BUILD_SENSOR_SENSIRION_SHT4X) sht4xHumid, sht4xTemp, #endif -#if defined BUILD_SENSOR_TALLY_COUNTER_I2C +#if defined(BUILD_SENSOR_TALLY_COUNTER_I2C) tallyEvents, #endif -#if defined BUILD_SENSOR_TI_INA219 +#if defined(BUILD_SENSOR_TI_INA219) inaVolt, inaCurrent, inaPower, #endif -#if defined BUILD_SENSOR_TURNER_CYCLOPS +#if defined(BUILD_SENSOR_TURNER_CYCLOPS) cyclopsVoltage, cyclopsChloro, cyclopsRWT, @@ -2777,62 +2777,62 @@ Variable* variableList[] = { cyclopsTryptophan, cyclopsRedChloro, #endif -#if defined BUILD_SENSOR_ANALOG_ELEC_CONDUCTIVITY +#if defined(BUILD_SENSOR_ANALOG_ELEC_CONDUCTIVITY) analogEc_cond, analogEc_spcond, #endif -#if defined BUILD_SENSOR_VEGA_PULS21 +#if defined(BUILD_SENSOR_VEGA_PULS21) VegaPulsStage, VegaPulsDistance, VegaPulsTemp, VegaPulsRelia, VegaPulsError, #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y504 +#if defined(BUILD_SENSOR_YOSEMITECH_Y504) y504DOpct, y504DOmgL, y504Temp, #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y510 +#if defined(BUILD_SENSOR_YOSEMITECH_Y510) y510Turb, y510Temp, #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y511 +#if defined(BUILD_SENSOR_YOSEMITECH_Y511) y511Turb, y511Temp, #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y514 +#if defined(BUILD_SENSOR_YOSEMITECH_Y514) y514Chloro, y514Temp, #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y520 +#if defined(BUILD_SENSOR_YOSEMITECH_Y520) y520Cond, y520Temp, #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y532 +#if defined(BUILD_SENSOR_YOSEMITECH_Y532) y532Voltage, y532pH, y532Temp, #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y533 +#if defined(BUILD_SENSOR_YOSEMITECH_Y533) y533ORP, y533Temp, #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y551 +#if defined(BUILD_SENSOR_YOSEMITECH_Y551) y551COD, y551Turbid, y551Temp, #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y560 +#if defined(BUILD_SENSOR_YOSEMITECH_Y560) y560NH4_N, y560pH, y560Temp, #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y700 +#if defined(BUILD_SENSOR_YOSEMITECH_Y700) y700Pres, y700Temp, #endif -#if defined BUILD_SENSOR_YOSEMITECH_Y4000 +#if defined(BUILD_SENSOR_YOSEMITECH_Y4000) y4000DO, y4000Turb, y4000Cond, @@ -2842,7 +2842,7 @@ Variable* variableList[] = { y4000Chloro, y4000BGA, #endif -#if defined BUILD_SENSOR_ZEBRA_TECH_D_OPTO +#if defined(BUILD_SENSOR_ZEBRA_TECH_D_OPTO) dOptoDOpct, dOptoDOmgL, dOptoTemp, @@ -2875,7 +2875,7 @@ Logger dataLogger(LoggerID, loggingInterval, &varArray); /** End [loggers] */ -#if defined BUILD_PUB_ENVIRO_DIY_PUBLISHER +#if defined(BUILD_PUB_ENVIRO_DIY_PUBLISHER) // ========================================================================== // A Publisher to Monitor My Watershed / EnviroDIY Data Sharing Portal // ========================================================================== @@ -2895,7 +2895,7 @@ EnviroDIYPublisher EnviroDIYPOST(dataLogger, &modem.gsmClient, #endif -#if defined BUILD_PUB_DREAM_HOST_PUBLISHER +#if defined(BUILD_PUB_DREAM_HOST_PUBLISHER) // ========================================================================== // A Publisher to DreamHost // ========================================================================== @@ -2913,7 +2913,7 @@ DreamHostPublisher DreamHostGET(dataLogger, &modem.gsmClient, #endif -#if defined BUILD_PUB_THING_SPEAK_PUBLISHER +#if defined(BUILD_PUB_THING_SPEAK_PUBLISHER) // ========================================================================== // ThingSpeak Data Publisher // ========================================================================== @@ -2938,7 +2938,7 @@ ThingSpeakPublisher TsMqtt(dataLogger, &modem.gsmClient, thingSpeakMQTTKey, #endif -#if defined BUILD_PUB_UBIDOTS_PUBLISHER +#if defined(BUILD_PUB_UBIDOTS_PUBLISHER) // ========================================================================== // Ubidots Data Publisher // ========================================================================== @@ -2996,7 +2996,7 @@ void setup() { // Wait for USB connection to be established by PC // NOTE: Only use this when debugging - if not connected to a PC, this // could prevent the script from starting -#if defined SERIAL_PORT_USBVIRTUAL +#if defined(SERIAL_PORT_USBVIRTUAL) while (!SERIAL_PORT_USBVIRTUAL && (millis() < 10000L)) { // wait } @@ -3023,11 +3023,11 @@ void setup() { /** Start [setup_softserial] */ // Allow interrupts for software serial -#if defined BUILD_TEST_SOFTSERIAL +#if defined(BUILD_TEST_SOFTSERIAL) enableInterrupt(softSerialRx, SoftwareSerial_ExtInts::handle_interrupt, CHANGE); #endif -#if defined BUILD_TEST_NEOSWSERIAL +#if defined(BUILD_TEST_NEOSWSERIAL) enableInterrupt(neoSSerial1Rx, neoSSerial1ISR, CHANGE); #endif /** End [setup_softserial] */ @@ -3040,7 +3040,7 @@ void setup() { // all currently supported modbus sensors use 9600 baud modbusSerial.begin(9600); -#if defined BUILD_SENSOR_MAX_BOTIX_SONAR +#if defined(BUILD_SENSOR_MAX_BOTIX_SONAR) // Start the SoftwareSerial stream for the sonar; it will always be at 9600 // baud sonarSerial.begin(9600); @@ -3050,7 +3050,7 @@ void setup() { // Assign pins SERCOM functionality for SAMD boards // NOTE: This must happen *after* the various serial.begin statements /** Start [setup_samd_pins] */ -#if defined ARDUINO_ARCH_SAMD +#if defined(ARDUINO_ARCH_SAMD) #ifndef ENABLE_SERIAL2 pinPeripheral(10, PIO_SERCOM); // Serial2 Tx/Dout = SERCOM1 Pad #2 pinPeripheral(11, PIO_SERCOM); // Serial2 Rx/Din = SERCOM1 Pad #0 @@ -3116,7 +3116,7 @@ void setup() { /** End [setup_esp] */ #endif -#if defined BUILD_TEST_SKYWIRE +#if defined(BUILD_TEST_SKYWIRE) /** Start [setup_skywire] */ modem.setModemStatusLevel(LOW); // If using CTS, LOW modem.setModemWakeLevel(HIGH); // Skywire dev board inverts the signal @@ -3124,7 +3124,7 @@ void setup() { /** End [setup_skywire] */ #endif -#if defined BUILD_MODEM_SIM_COM_SIM7080 +#if defined(BUILD_MODEM_SIM_COM_SIM7080) /** Start [setup_sim7080] */ modem.setModemWakeLevel(HIGH); // ModuleFun Bee inverts the signal modem.setModemResetLevel(HIGH); // ModuleFun Bee inverts the signal @@ -3143,7 +3143,7 @@ void setup() { /** End [setup_sim7080] */ #endif -#if defined BUILD_MODEM_DIGI_XBEE_CELLULAR_TRANSPARENT +#if defined(BUILD_MODEM_DIGI_XBEE_CELLULAR_TRANSPARENT) /** Start [setup_xbeec_carrier] */ // Extra modem set-up Serial.println(F("Waking modem and setting Cellular Carrier Options...")); @@ -3180,7 +3180,7 @@ void setup() { #endif -#if defined BUILD_MODEM_DIGI_XBEE_LTE_BYPASS +#if defined(BUILD_MODEM_DIGI_XBEE_LTE_BYPASS) /** Start [setup_r4_carrrier] */ // Extra modem set-up Serial.println(F("Waking modem and setting Cellular Carrier Options...")); diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index ab60df4bd..5b0f0f122 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -37,7 +37,7 @@ volatile bool Logger::startTesting = false; // Initialize the RTC for the SAMD boards using build in RTC // Needed for static instances -#if not defined(MS_SAMD_DS3231) && defined(ARDUINO_ARCH_SAMD) +#if !defined(MS_SAMD_DS3231) && defined(ARDUINO_ARCH_SAMD) RTCZero Logger::zero_sleep_rtc; #endif @@ -459,7 +459,7 @@ uint32_t Logger::getNowLocalEpoch(void) { return currentEpochTime; } -#if defined(MS_SAMD_DS3231) || not defined(ARDUINO_ARCH_SAMD) +#if defined(MS_SAMD_DS3231) || !defined(ARDUINO_ARCH_SAMD) uint32_t Logger::getNowUTCEpoch(void) { return rtc.now().getEpoch(); @@ -468,7 +468,7 @@ void Logger::setNowUTCEpoch(uint32_t ts) { rtc.setEpoch(ts); } -#elif defined ARDUINO_ARCH_SAMD +#elif defined(ARDUINO_ARCH_SAMD) uint32_t Logger::getNowUTCEpoch(void) { return zero_sleep_rtc.getEpoch(); @@ -719,7 +719,7 @@ void Logger::systemSleep(void) { // Send a message that we're getting ready MS_DBG(F("Preparing processor for sleep. ZZzzz...")); -#if defined(MS_SAMD_DS3231) || not defined(ARDUINO_ARCH_SAMD) +#if defined(MS_SAMD_DS3231) || !defined(ARDUINO_ARCH_SAMD) // Unfortunately, because of the way the alarm on the DS3231 is set up, it // cannot interrupt on any frequencies other than every second, minute, @@ -741,7 +741,7 @@ void Logger::systemSleep(void) { // attach the interrupt enableInterrupt(_mcuWakePin, wakeISR, CHANGE); -#if defined ARDUINO_ARCH_SAMD && not defined(__SAMD51__) +#if defined(ARDUINO_ARCH_SAMD) && !defined(__SAMD51__) // Reconfigure the clock after attaching the interrupt // This is needed because the attachInterrupt function will reconfigure the // clock source for the EIC to GCLK0 every time a new interrupt is attached @@ -759,9 +759,9 @@ void Logger::systemSleep(void) { EExt_Interrupts in = g_APinDescription[_mcuWakePin].ulExtInt; // Enable wakeup capability on pin in case being used during sleep EIC->WAKEUP.reg |= (1 << in); -#endif // defined ARDUINO_ARCH_SAMD && not defined(__SAMD51__) +#endif // #if defined(ARDUINO_ARCH_SAMD) && ! defined(__SAMD51__) -#elif defined ARDUINO_ARCH_SAMD +#elif defined(ARDUINO_ARCH_SAMD) // Make sure interrupts are enabled for the clock NVIC_EnableIRQ(RTC_IRQn); // enable RTC interrupt @@ -777,7 +777,7 @@ void Logger::systemSleep(void) { zero_sleep_rtc.setAlarmSeconds(59); zero_sleep_rtc.enableAlarm(zero_sleep_rtc.MATCH_SS); -#endif // defined(MS_SAMD_DS3231) || not defined(ARDUINO_ARCH_SAMD) +#endif // defined(MS_SAMD_DS3231) || ! defined(ARDUINO_ARCH_SAMD) // Stop any I2C connections @@ -807,13 +807,13 @@ void Logger::systemSleep(void) { #if defined(STANDARD_SERIAL_OUTPUT) STANDARD_SERIAL_OUTPUT.flush(); // for debugging #endif -#if defined DEBUGGING_SERIAL_OUTPUT +#if defined(DEBUGGING_SERIAL_OUTPUT) DEBUGGING_SERIAL_OUTPUT.flush(); // for debugging #endif -#if defined ARDUINO_ARCH_SAMD +#if defined(ARDUINO_ARCH_SAMD) -#if not defined(USE_TINYUSB) && defined(USBCON) +#if !defined(USE_TINYUSB) && defined(USBCON) // Detach the USB, iff not using TinyUSB MS_DEEP_DBG(F("Detaching USB")); Serial.flush(); // wait for any outgoing messages on Serial = USB @@ -859,7 +859,7 @@ void Logger::systemSleep(void) { __DSB(); // Data sync to ensure outgoing memory accesses complete __WFI(); // Wait for interrupt (places device in sleep mode) -#elif defined ARDUINO_ARCH_AVR +#elif defined(ARDUINO_ARCH_AVR) // Disable USB if it exists #ifdef USBCON @@ -918,19 +918,19 @@ void Logger::systemSleep(void) { // --------------------------------------------------------------------- // -- The portion below this happens on wake up, after any wake ISR's -- -#if defined ARDUINO_ARCH_SAMD -#if not defined(__SAMD51__) +#if defined(ARDUINO_ARCH_SAMD) +#if !defined(__SAMD51__) // Enable systick interrupt SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; #endif // Reattach the USB -#if not defined(USE_TINYUSB) && defined(USBCON) +#if !defined(USE_TINYUSB) && defined(USBCON) USBDevice.init(); USBDevice.attach(); #endif #endif -#if defined ARDUINO_ARCH_AVR +#if defined(ARDUINO_ARCH_AVR) // Temporarily disables interrupts, so no mistakes are made when writing // to the processor registers @@ -977,7 +977,7 @@ void Logger::systemSleep(void) { // the timeout period is a useless delay. Wire.setTimeout(0); -#if defined(MS_SAMD_DS3231) || not defined(ARDUINO_ARCH_SAMD) +#if defined(MS_SAMD_DS3231) || !defined(ARDUINO_ARCH_SAMD) // Stop the clock from sending out any interrupts while we're awake. // There's no reason to waste thought on the clock interrupt if it // happens while the processor is awake and doing other things. @@ -986,7 +986,7 @@ void Logger::systemSleep(void) { // Detach the from the pin disableInterrupt(_mcuWakePin); -#elif defined ARDUINO_ARCH_SAMD +#elif defined(ARDUINO_ARCH_SAMD) MS_DEEP_DBG(F("Unsetting the alarm on the built in RTC")); zero_sleep_rtc.disableAlarm(); #endif @@ -1421,7 +1421,7 @@ void Logger::begin() { // Enable the watchdog watchDogTimer.enableWatchDog(); -#if not defined(MS_SAMD_DS3231) && defined(ARDUINO_ARCH_SAMD) +#if !defined(MS_SAMD_DS3231) && defined(ARDUINO_ARCH_SAMD) MS_DBG(F("Beginning internal real time clock")); zero_sleep_rtc.begin(); #endif @@ -1453,7 +1453,7 @@ void Logger::begin() { setLoggerPins(_mcuWakePin, _SDCardSSPin, _SDCardPowerPin, _buttonPin, _ledPin); -#if defined(MS_SAMD_DS3231) || not defined(ARDUINO_ARCH_SAMD) +#if defined(MS_SAMD_DS3231) || !defined(ARDUINO_ARCH_SAMD) MS_DBG(F("Beginning DS3231 real time clock")); rtc.begin(); #endif diff --git a/src/LoggerBase.h b/src/LoggerBase.h index c5244dce2..36c1ad97c 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -41,7 +41,7 @@ // Bring in the libraries to handle the processor sleep/standby modes // The SAMD library can also the built-in clock on those modules #if defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_SAMD_ZERO) -#if not defined(MS_SAMD_DS3231) +#if !defined(MS_SAMD_DS3231) #include #endif #include "WatchDogs/WatchDogSAMD.h" @@ -726,7 +726,7 @@ class Logger { static int8_t getTZOffset(void); #if (defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_SAMD_ZERO)) && \ - not defined(MS_SAMD_DS3231) + !defined(MS_SAMD_DS3231) /** * @brief The RTC object. * diff --git a/src/ModSensorDebugger.h b/src/ModSensorDebugger.h index 7561c33ff..219255c92 100644 --- a/src/ModSensorDebugger.h +++ b/src/ModSensorDebugger.h @@ -25,7 +25,7 @@ #if defined(SERIAL_PORT_USBVIRTUAL) // #define Serial SERIAL_PORT_USBVIRTUAL #define STANDARD_SERIAL_OUTPUT SERIAL_PORT_USBVIRTUAL -#elif defined __AVR__ || defined ARDUINO_ARCH_AVR +#elif defined(__AVR__) || defined(ARDUINO_ARCH_AVR) #define STANDARD_SERIAL_OUTPUT Serial #endif #endif // ifndef STANDARD_SERIAL_OUTPUT @@ -68,7 +68,7 @@ static void PRINTOUT(T head, Args... tail) { #if defined(SERIAL_PORT_USBVIRTUAL) // #define Serial SERIAL_PORT_USBVIRTUAL #define DEBUGGING_SERIAL_OUTPUT SERIAL_PORT_USBVIRTUAL -#elif defined __AVR__ || defined ARDUINO_ARCH_AVR +#elif defined(__AVR__) || defined(ARDUINO_ARCH_AVR) #define DEBUGGING_SERIAL_OUTPUT Serial #endif #endif // ifndef DEBUGGING_SERIAL_OUTPUT @@ -166,7 +166,7 @@ static void MS_DBG(T head, Args... tail) { #if defined(SERIAL_PORT_USBVIRTUAL) // #define Serial SERIAL_PORT_USBVIRTUAL #define DEEP_DEBUGGING_SERIAL_OUTPUT SERIAL_PORT_USBVIRTUAL -#elif defined __AVR__ || defined ARDUINO_ARCH_AVR +#elif defined(__AVR__) || defined(ARDUINO_ARCH_AVR) #define DEEP_DEBUGGING_SERIAL_OUTPUT Serial #endif #endif // ifndef DEEP_DEBUGGING_SERIAL_OUTPUT @@ -221,7 +221,7 @@ static void MS_DEEP_DBG(T head, Args... tail) { /*** -#if defined (__AVR__) || defined (ARDUINO_ARCH_AVR) +#if defined(__AVR__) || defined (ARDUINO_ARCH_AVR) typedef const __FlashStringHelper* GsmConstStr; #define GFP(x) (reinterpret_cast(x)) #define GF(x) F(x) diff --git a/src/modems/LoggerModemMacros.h b/src/modems/LoggerModemMacros.h index 37760b206..9123468e8 100644 --- a/src/modems/LoggerModemMacros.h +++ b/src/modems/LoggerModemMacros.h @@ -179,7 +179,7 @@ return success; \ } -#if defined TINY_GSM_MODEM_HAS_GPRS +#if defined(TINY_GSM_MODEM_HAS_GPRS) /** * @brief Creates an isInternetAvailable() function for a specific modem * subclass. @@ -321,7 +321,7 @@ MS_PRINT_DEBUG_TIMER, F("milliseconds.")); \ } -#else // from #if defined TINY_GSM_MODEM_HAS_GPRS (ie, this is wifi) +#else // from #if defined(TINY_GSM_MODEM_HAS_GPRS) (ie, this is wifi) /** * @brief Creates an isInternetAvailable() function for a specific @@ -452,7 +452,7 @@ MS_DBG(F("Disconnected from WiFi network after"), \ MS_PRINT_DEBUG_TIMER, F("milliseconds.")); \ } -#endif // #if defined TINY_GSM_MODEM_HAS_GPRS +#endif // #if defined(TINY_GSM_MODEM_HAS_GPRS) /** * @brief The port hosting the NIST "time" protocol (37) @@ -463,7 +463,7 @@ */ #define NIST_RESPONSE_BYTES 4 -#if !defined NIST_SERVER_RETRYS || defined(DOXYGEN) +#if !defined(NIST_SERVER_RETRYS) || defined(DOXYGEN) /** * @brief The number of retry attempts when connecting to the NIST server. */ diff --git a/src/publishers/ThingSpeakPublisher.cpp b/src/publishers/ThingSpeakPublisher.cpp index 3b070088a..15cb48a8b 100644 --- a/src/publishers/ThingSpeakPublisher.cpp +++ b/src/publishers/ThingSpeakPublisher.cpp @@ -102,7 +102,7 @@ void ThingSpeakPublisher::begin(Logger& baseLogger, // This sends the data to ThingSpeak // bool ThingSpeakPublisher::mqttThingSpeak(void) -int16_t ThingSpeakPublisher::publishData(Client* outClient, bool ) { +int16_t ThingSpeakPublisher::publishData(Client* outClient, bool) { bool retVal = false; // Make sure we don't have too many fields diff --git a/src/sensors/AOSongAM2315.h b/src/sensors/AOSongAM2315.h index 4313f5bb7..283e1b6ad 100644 --- a/src/sensors/AOSongAM2315.h +++ b/src/sensors/AOSongAM2315.h @@ -239,7 +239,7 @@ class AOSongAM2315 : public Sensor { /** * @brief An internal reference to the hardware Wire instance. */ - TwoWire* _i2c; + TwoWire* _i2c; /** * @brief Internal reference to the Adafruit sensor class */ diff --git a/src/sensors/AnalogElecConductivity.cpp b/src/sensors/AnalogElecConductivity.cpp index 397afb7dc..2e2e3f25e 100644 --- a/src/sensors/AnalogElecConductivity.cpp +++ b/src/sensors/AnalogElecConductivity.cpp @@ -45,7 +45,7 @@ float AnalogElecConductivity::readEC(uint8_t analogPinNum) { float EC_uScm = -9999; // units are uS per cm // Set the resolution for the processor ADC, only applies to SAMD boards. -#if !defined ARDUINO_ARCH_AVR +#if !defined(ARDUINO_ARCH_AVR) analogReadResolution(ANALOG_EC_ADC_RESOLUTION); #endif // ARDUINO_ARCH_AVR // Set the analog reference mode for the voltage measurement. diff --git a/src/sensors/AnalogElecConductivity.h b/src/sensors/AnalogElecConductivity.h index 601163055..800b398d8 100644 --- a/src/sensors/AnalogElecConductivity.h +++ b/src/sensors/AnalogElecConductivity.h @@ -179,7 +179,7 @@ * conductivity sensor depending on the processor and ADC in use. */ /**@{*/ -#if !defined ANALOG_EC_ADC_RESOLUTION || defined(DOXYGEN) +#if !defined(ANALOG_EC_ADC_RESOLUTION) || defined(DOXYGEN) /** * @brief Default resolution (in bits) of the voltage measurement * @@ -196,8 +196,8 @@ #define ANALOG_EC_ADC_RANGE (1 << ANALOG_EC_ADC_RESOLUTION) /* clang-format off */ -#if !defined ANALOG_EC_ADC_REFERENCE_MODE || defined (DOXYGEN) -#if defined (ARDUINO_ARCH_AVR) || defined (DOXYGEN) +#if ! defined (ANALOG_EC_ADC_REFERENCE_MODE) || defined (DOXYGEN) +#if defined(ARDUINO_ARCH_AVR) || defined (DOXYGEN) /** * @brief The voltage reference mode for the processor's ADC. * @@ -219,7 +219,7 @@ */ #define ANALOG_EC_ADC_REFERENCE_MODE DEFAULT #endif -#if defined (ARDUINO_ARCH_SAMD) || defined (DOXYGEN) +#if defined(ARDUINO_ARCH_SAMD) || defined (DOXYGEN) /** * @brief The voltage reference mode for the processor's ADC. * @@ -240,13 +240,13 @@ */ #define ANALOG_EC_ADC_REFERENCE_MODE AR_DEFAULT #endif -#if !defined ANALOG_EC_ADC_REFERENCE_MODE +#if ! defined (ANALOG_EC_ADC_REFERENCE_MODE) #error The processor ADC reference type must be defined! #endif // ANALOG_EC_ADC_REFERENCE_MODE #endif // ARDUINO_ARCH_SAMD /* clang-format on */ -#if !defined RSERIES_OHMS_DEF || defined(DOXYGEN) +#if !defined(RSERIES_OHMS_DEF) || defined(DOXYGEN) /** * @brief The default resistance (in ohms) of the measuring resistor. * This should not be less than 300 ohms when measuring EC in water. @@ -254,7 +254,7 @@ #define RSERIES_OHMS_DEF 499 #endif // RSERIES_OHMS_DEF -#if !defined SENSOREC_KONST_DEF || defined(DOXYGEN) +#if !defined(SENSOREC_KONST_DEF) || defined(DOXYGEN) /** * @brief Cell Constant For EC Measurements. * diff --git a/src/sensors/BoschBMP3xx.h b/src/sensors/BoschBMP3xx.h index 292b76d09..de4e351a1 100644 --- a/src/sensors/BoschBMP3xx.h +++ b/src/sensors/BoschBMP3xx.h @@ -169,7 +169,7 @@ * calculate altitude by the BME3xx. */ /**@{*/ -#ifndef SEALEVELPRESSURE_HPA || defined(DOXYGEN) +#if !defined(SEALEVELPRESSURE_HPA) || defined(DOXYGEN) /// The atmospheric pressure at sea level #define SEALEVELPRESSURE_HPA (1013.25) #endif diff --git a/src/sensors/EverlightALSPT19.cpp b/src/sensors/EverlightALSPT19.cpp index 59f262fee..3b3f43653 100644 --- a/src/sensors/EverlightALSPT19.cpp +++ b/src/sensors/EverlightALSPT19.cpp @@ -44,7 +44,7 @@ bool EverlightALSPT19::addSingleMeasurementResult(void) { if (bitRead(_sensorStatus, 6)) { // Set the resolution for the processor ADC, only applies to SAMD // boards. -#if !defined ARDUINO_ARCH_AVR +#if !defined(ARDUINO_ARCH_AVR) analogReadResolution(ALSPT19_ADC_RESOLUTION); #endif // ARDUINO_ARCH_AVR // Set the analog reference mode for the voltage measurement. diff --git a/src/sensors/EverlightALSPT19.h b/src/sensors/EverlightALSPT19.h index 1fe5ff834..db59fa0e4 100644 --- a/src/sensors/EverlightALSPT19.h +++ b/src/sensors/EverlightALSPT19.h @@ -101,7 +101,7 @@ * on the processor and ADC in use. */ /**@{*/ -#if !defined ALSPT19_ADC_RESOLUTION || defined(DOXYGEN) +#if !defined(ALSPT19_ADC_RESOLUTION) || defined(DOXYGEN) /** * @brief Default resolution (in bits) of the voltage measurement * @@ -118,8 +118,8 @@ #define ALSPT19_ADC_RANGE (1 << ALSPT19_ADC_RESOLUTION) /* clang-format off */ -#if !defined ALSPT19_ADC_REFERENCE_MODE || defined (DOXYGEN) -#if defined (ARDUINO_ARCH_AVR) || defined (DOXYGEN) +#if ! defined (ALSPT19_ADC_REFERENCE_MODE) || defined (DOXYGEN) +#if defined(ARDUINO_ARCH_AVR) || defined (DOXYGEN) /** * @brief The voltage reference mode for the processor's ADC. * @@ -141,7 +141,7 @@ */ #define ALSPT19_ADC_REFERENCE_MODE DEFAULT #endif -#if defined (ARDUINO_ARCH_SAMD) || defined (DOXYGEN) +#if defined(ARDUINO_ARCH_SAMD) || defined (DOXYGEN) /** * @brief The voltage reference mode for the processor's ADC. * @@ -162,7 +162,7 @@ */ #define ALSPT19_ADC_REFERENCE_MODE AR_DEFAULT #endif -#if !defined ALSPT19_ADC_REFERENCE_MODE +#if ! defined (ALSPT19_ADC_REFERENCE_MODE) #error The processor ADC reference type must be defined! #endif // ALSPT19_ADC_REFERENCE_MODE #endif // ARDUINO_ARCH_SAMD diff --git a/src/sensors/PaleoTerraRedox.cpp b/src/sensors/PaleoTerraRedox.cpp index 12ea8cb07..922f68250 100644 --- a/src/sensors/PaleoTerraRedox.cpp +++ b/src/sensors/PaleoTerraRedox.cpp @@ -16,7 +16,7 @@ // Constructors -#if defined MS_PALEOTERRA_SOFTWAREWIRE +#if defined(MS_PALEOTERRA_SOFTWAREWIRE) PaleoTerraRedox::PaleoTerraRedox(SoftwareWire* theI2C, int8_t powerPin, uint8_t i2cAddressHex, uint8_t measurementsToAverage) @@ -57,7 +57,7 @@ PaleoTerraRedox::PaleoTerraRedox(int8_t powerPin, uint8_t i2cAddressHex, // Destructors -#if defined MS_PALEOTERRA_SOFTWAREWIRE +#if defined(MS_PALEOTERRA_SOFTWAREWIRE) // If we created a new SoftwareWire instance, we need to destroy it or // there will be a memory leak PaleoTerraRedox::~PaleoTerraRedox() { @@ -68,8 +68,8 @@ PaleoTerraRedox::~PaleoTerraRedox() {} #endif -String PaleoTerraRedox::getSensorLocation(void) { -#if defined MS_PALEOTERRA_SOFTWAREWIRE +String PaleoTerraRedox::getSensorLocation(void) { +#if defined(MS_PALEOTERRA_SOFTWAREWIRE) String address = F("SoftwareWire"); if (_dataPin >= 0) address += _dataPin; address += F("_0x"); diff --git a/src/sensors/PaleoTerraRedox.h b/src/sensors/PaleoTerraRedox.h index fbf6ece0f..2ca5e616d 100644 --- a/src/sensors/PaleoTerraRedox.h +++ b/src/sensors/PaleoTerraRedox.h @@ -75,7 +75,7 @@ #include "SensorBase.h" #include -#if defined MS_PALEOTERRA_SOFTWAREWIRE +#if defined(MS_PALEOTERRA_SOFTWAREWIRE) #include // Testato's SoftwareWire #endif @@ -272,7 +272,7 @@ class PaleoTerraRedox : public Sensor { * @brief The I2C address of the redox sensor. */ uint8_t _i2cAddressHex; -#if defined MS_PALEOTERRA_SOFTWAREWIRE +#if defined(MS_PALEOTERRA_SOFTWAREWIRE) /** * @brief An internal reference to the SoftwareWire instance. */ diff --git a/src/sensors/RainCounterI2C.cpp b/src/sensors/RainCounterI2C.cpp index b2777f1cf..0f62dc25c 100644 --- a/src/sensors/RainCounterI2C.cpp +++ b/src/sensors/RainCounterI2C.cpp @@ -13,7 +13,7 @@ // The constructors -#if defined MS_RAIN_SOFTWAREWIRE +#if defined(MS_RAIN_SOFTWAREWIRE) RainCounterI2C::RainCounterI2C(SoftwareWire* theI2C, uint8_t i2cAddressHex, float rainPerTip) : Sensor("RainCounterI2C", BUCKET_NUM_VARIABLES, BUCKET_WARM_UP_TIME_MS, @@ -52,7 +52,7 @@ RainCounterI2C::RainCounterI2C(uint8_t i2cAddressHex, float rainPerTip) // Destructors -#if defined MS_RAIN_SOFTWAREWIRE +#if defined(MS_RAIN_SOFTWAREWIRE) // If we created a new SoftwareWire instance, we need to destroy it or // there will be a memory leak RainCounterI2C::~RainCounterI2C() { @@ -63,8 +63,8 @@ RainCounterI2C::~RainCounterI2C() {} #endif -String RainCounterI2C::getSensorLocation(void) { -#if defined MS_RAIN_SOFTWAREWIRE +String RainCounterI2C::getSensorLocation(void) { +#if defined(MS_RAIN_SOFTWAREWIRE) String address = F("SoftwareWire"); if (_dataPin >= 0) address += _dataPin; address += F("_0x"); diff --git a/src/sensors/RainCounterI2C.h b/src/sensors/RainCounterI2C.h index 9e084bd12..759e6ec1d 100644 --- a/src/sensors/RainCounterI2C.h +++ b/src/sensors/RainCounterI2C.h @@ -85,7 +85,7 @@ #include "SensorBase.h" #include -#if defined MS_RAIN_SOFTWAREWIRE +#if defined(MS_RAIN_SOFTWAREWIRE) #include // Testato's SoftwareWire #endif From c65ade7b75bded20e818b43662d633a990d2ad51 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 18 Sep 2024 11:34:16 -0400 Subject: [PATCH 130/138] minor clang format applications Signed-off-by: Sara Damiano --- src/WatchDogs/WatchDogSAMD.cpp | 2 +- src/sensors/KellerParent.h | 4 ++-- src/sensors/MaximDS18.h | 2 +- src/sensors/ProcessorStats.cpp | 6 +++--- src/sensors/TIADS1x15.h | 2 +- src/sensors/TurnerCyclops.h | 3 ++- src/sensors/YosemitechParent.h | 4 ++-- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/WatchDogs/WatchDogSAMD.cpp b/src/WatchDogs/WatchDogSAMD.cpp index 4c176ad8f..5f49ecfe8 100644 --- a/src/WatchDogs/WatchDogSAMD.cpp +++ b/src/WatchDogs/WatchDogSAMD.cpp @@ -33,7 +33,7 @@ void extendedWatchDogSAMD::setupWatchDog(uint32_t resetTime_s) { extendedWatchDogSAMD::_barksUntilReset, F("times before the reset.")); -// Disable watchdog for config + // Disable watchdog for config MS_DEEP_DBG(F("Disabling the watchdog for configuration.")); #if defined(__SAMD51__) WDT->CTRLA.reg = 0; diff --git a/src/sensors/KellerParent.h b/src/sensors/KellerParent.h index 19bf79322..ad048a3fd 100644 --- a/src/sensors/KellerParent.h +++ b/src/sensors/KellerParent.h @@ -268,12 +268,12 @@ class KellerParent : public Sensor { /** * @brief Private reference to the Keller sensor's modbus address */ - byte _modbusAddress; + byte _modbusAddress; /** * @brief Private reference to the stream for communciation with the * Keller sensor. */ - Stream* _stream; + Stream* _stream; /** * @brief Private reference to the RS-485 adapter's flow direction control * pin. diff --git a/src/sensors/MaximDS18.h b/src/sensors/MaximDS18.h index dbc94a643..1a85c800c 100644 --- a/src/sensors/MaximDS18.h +++ b/src/sensors/MaximDS18.h @@ -264,7 +264,7 @@ class MaximDS18 : public Sensor { * @brief True to indicate that the address of the OneWire device was * specified. If false, the first device to respond will be the one used. */ - bool _addressKnown; + bool _addressKnown; /** * @brief An internal OneWire instance to communicate with any OneWire * devices (not just Maxim/Dallas temperature ICs) diff --git a/src/sensors/ProcessorStats.cpp b/src/sensors/ProcessorStats.cpp index eb149027d..f649ebc92 100644 --- a/src/sensors/ProcessorStats.cpp +++ b/src/sensors/ProcessorStats.cpp @@ -21,7 +21,7 @@ ProcessorStats::ProcessorStats(const char* version) #elif defined(ARDUINO_AVR_FEATHER32U4) || defined(ARDUINO_SAMD_FEATHER_M0) || \ defined(SAMD_FEATHER_M0) || defined(ARDUINO_SAMD_FEATHER_M0_EXPRESS) || \ defined(SAMD_FEATHER_M0_EXPRESS) - _batteryPin = 9; + _batteryPin = 9; #elif defined(ARDUINO_SODAQ_ONE) || defined(ARDUINO_SODAQ_ONE_BETA) || \ defined(ARDUINO_AVR_SODAQ_NDOGO) _batteryPin = 10; @@ -108,7 +108,7 @@ bool ProcessorStats::addSingleMeasurementResult(void) { MS_DBG(F("Raw battery pin reading in bits:"), rawBattery); sensorValue_battery = (3.3 / 1023.) * 1.47 * rawBattery; MS_DBG(F("Battery in Volts:"), sensorValue_battery); - } +} #elif defined(ARDUINO_AVR_SODAQ_NDOGO) || defined(ARDUINO_SODAQ_AUTONOMO) || \ defined(ARDUINO_AVR_SODAQ_MBILI) @@ -140,7 +140,7 @@ bool ProcessorStats::addSingleMeasurementResult(void) { float sensorValue_freeRam = FreeRam(); #else - float sensorValue_freeRam = -9999; +float sensorValue_freeRam = -9999; #endif verifyAndAddMeasurementResult(PROCESSOR_RAM_VAR_NUM, sensorValue_freeRam); diff --git a/src/sensors/TIADS1x15.h b/src/sensors/TIADS1x15.h index 1253492b1..44a3ade94 100644 --- a/src/sensors/TIADS1x15.h +++ b/src/sensors/TIADS1x15.h @@ -308,7 +308,7 @@ class TIADS1x15 : public Sensor { /** * @brief Internal reference to the gain setting for the TI-ADS1x15 */ - float _gain; + float _gain; /** * @brief Internal reference to the I2C address of the TI-ADS1x15 */ diff --git a/src/sensors/TurnerCyclops.h b/src/sensors/TurnerCyclops.h index 9ef9d6518..b1396d3af 100644 --- a/src/sensors/TurnerCyclops.h +++ b/src/sensors/TurnerCyclops.h @@ -587,7 +587,8 @@ class TurnerCyclops_Fluorescein : public Variable { : Variable((const uint8_t)CYCLOPS_VAR_NUM, (uint8_t)CYCLOPS_RESOLUTION, "fluorescein", "partPerBillion", "CyclopsFluorescein") {} /** - * @brief Destroy the Turner Cyclops Fluorescein variable object - no action needed. + * @brief Destroy the Turner Cyclops Fluorescein variable object - no action + * needed. */ ~TurnerCyclops_Fluorescein() {} }; diff --git a/src/sensors/YosemitechParent.h b/src/sensors/YosemitechParent.h index 3dcb70328..b63e67cd9 100644 --- a/src/sensors/YosemitechParent.h +++ b/src/sensors/YosemitechParent.h @@ -265,12 +265,12 @@ class YosemitechParent : public Sensor { /** * @brief Private reference to the Yosemitech sensor's modbus address */ - byte _modbusAddress; + byte _modbusAddress; /** * @brief Private reference to the stream for communciation with the * Yosemitech sensor. */ - Stream* _stream; + Stream* _stream; /** * @brief Private reference to the RS-485 adapter's flow direction control * pin. From 4f6a82058e52e5c5f444260dd975193ca6292e66 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 18 Sep 2024 11:34:29 -0400 Subject: [PATCH 131/138] update ci ini Signed-off-by: Sara Damiano --- continuous_integration/platformio.ini | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/continuous_integration/platformio.ini b/continuous_integration/platformio.ini index 480331f56..c6ca1e02e 100644 --- a/continuous_integration/platformio.ini +++ b/continuous_integration/platformio.ini @@ -28,8 +28,9 @@ build_flags = -D NEOSWSERIAL_EXTERNAL_PCINT [env:mayfly] -board = mayfly +framework = arduino platform = atmelavr +board = mayfly lib_ignore = ${env.lib_ignore} RTCZero @@ -38,6 +39,7 @@ build_flags = ${env.build_flags} [env:mega] +framework = arduino platform = atmelavr board = megaatmega2560 lib_ignore = @@ -48,6 +50,7 @@ build_flags = ${env.build_flags} [env:zero] +framework = arduino platform = atmelsam board = zeroUSB lib_ignore = @@ -60,6 +63,7 @@ build_flags = ${env.build_flags} [env:feather_m0] +framework = arduino platform = atmelsam board = adafruit_feather_m0 lib_ignore = @@ -73,6 +77,7 @@ build_flags = build_unflags = -D USE_TINYUSB ; [env:feather_m4] +; framework = arduino ; platform = atmelsam ; board = adafruit_feather_m4 ; lib_ignore = @@ -88,6 +93,7 @@ build_unflags = -D USE_TINYUSB ; build_unflags = -D USE_TINYUSB ; [env:grandcentral_m4] +; framework = arduino ; platform = atmelsam ; board = adafruit_grandcentral_m4 ; lib_ignore = From 86095af77eaa1f14345be0f0b6e028924e053438 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Wed, 18 Sep 2024 11:44:22 -0400 Subject: [PATCH 132/138] Consistently check for both ARDUINO_ARCH_AVR and __AVR__ Signed-off-by: Sara Damiano --- examples/menu_a_la_carte/menu_a_la_carte.ino | 2 +- src/LoggerBase.h | 2 +- src/ModSensorInterrupts.h | 2 +- src/WatchDogs/WatchDogAVR.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/menu_a_la_carte/menu_a_la_carte.ino b/examples/menu_a_la_carte/menu_a_la_carte.ino index 5720f93fe..50d99c088 100644 --- a/examples/menu_a_la_carte/menu_a_la_carte.ino +++ b/examples/menu_a_la_carte/menu_a_la_carte.ino @@ -48,7 +48,7 @@ // peripherals as possible. In some cases (ie, modbus communication) many // sensors can share the same serial port. -#if defined(ARDUINO_ARCH_AVR) || defined(__AVR__) // For AVR boards +#if defined(__AVR__) || defined(ARDUINO_ARCH_AVR) // For AVR boards // Unfortunately, most AVR boards have only one or two hardware serial ports, // so we'll set up three types of extra software serial ports to use diff --git a/src/LoggerBase.h b/src/LoggerBase.h index 36c1ad97c..b1f6e2c73 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -45,7 +45,7 @@ #include #endif #include "WatchDogs/WatchDogSAMD.h" -#elif defined(ARDUINO_ARCH_AVR) || defined(__AVR__) +#elif defined(__AVR__) || defined(ARDUINO_ARCH_AVR) #include #include #include "WatchDogs/WatchDogAVR.h" diff --git a/src/ModSensorInterrupts.h b/src/ModSensorInterrupts.h index 808475155..a467bb4b8 100644 --- a/src/ModSensorInterrupts.h +++ b/src/ModSensorInterrupts.h @@ -16,7 +16,7 @@ #include -#if defined(__AVR__) +#if defined(__AVR__) || defined(ARDUINO_ARCH_AVR) // #define LIBCALL_ENABLEINTERRUPT // To prevent compiler/linker crashes #include // To handle external and pin change interrupts #else diff --git a/src/WatchDogs/WatchDogAVR.cpp b/src/WatchDogs/WatchDogAVR.cpp index ade6956a6..b00f96445 100644 --- a/src/WatchDogs/WatchDogAVR.cpp +++ b/src/WatchDogs/WatchDogAVR.cpp @@ -13,7 +13,7 @@ // Be careful to use a platform-specific conditional include to only make the // code visible for the appropriate platform. Arduino will try to compile and // link all .cpp files regardless of platform. -#if defined(ARDUINO_ARCH_AVR) || defined(__AVR__) +#if defined(__AVR__) || defined(ARDUINO_ARCH_AVR) #include #include From 95e70108dbe8ef2b86a0a19d5c8ce0ba033fa44b Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 19 Sep 2024 13:50:11 -0400 Subject: [PATCH 133/138] ignore one example Signed-off-by: Sara Damiano --- .gitignore | 1 + continuous_integration/generate_job_matrix.py | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index bca6ee90c..e2b45d07a 100644 --- a/.gitignore +++ b/.gitignore @@ -110,3 +110,4 @@ ex_one_offs/* output_deep.txt output_deep+.txt envDump.txt +-Q diff --git a/continuous_integration/generate_job_matrix.py b/continuous_integration/generate_job_matrix.py index 173638746..f5b1eadf5 100644 --- a/continuous_integration/generate_job_matrix.py +++ b/continuous_integration/generate_job_matrix.py @@ -267,14 +267,18 @@ def snake_to_camel(snake_str): for compiler, command_list in zip( compilers, [arduino_ex_commands, pio_ex_commands] ): - command_list.extend( - create_logged_command( - compiler=compiler, - group_title=example, - code_subfolder=example, - pio_env=pio_env, + if compiler == "Arduino CLI" and example == "data_saving": + # skip this one, it's too big + pass + else: + command_list.extend( + create_logged_command( + compiler=compiler, + group_title=example, + code_subfolder=example, + pio_env=pio_env, + ) ) - ) arduino_job_matrix.append( { From ba8493d0a7b9d9f04eaee3b6fe453a82f56453f1 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 19 Sep 2024 15:07:52 -0400 Subject: [PATCH 134/138] mcss render math Signed-off-by: Sara Damiano --- docs/Doxyfile | 2 +- docs/mcss-conf.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/Doxyfile b/docs/Doxyfile index 5f44b6603..916295cae 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1843,7 +1843,7 @@ HTML_FORMULA_FORMAT = png # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. -FORMULA_FONTSIZE = 10 +FORMULA_FONTSIZE = 14 # The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands # to create new LaTeX commands to be used in formulas as building blocks. See diff --git a/docs/mcss-conf.py b/docs/mcss-conf.py index f15b3a6d7..02f0cec67 100644 --- a/docs/mcss-conf.py +++ b/docs/mcss-conf.py @@ -174,3 +174,5 @@ DESKTOP_LOGO = "gp-desktop-logo.png" MOBILE_LOGO = "gp-mobile-logo.png" SCROLLING_LOGO = "gp-scrolling-logo.png" +M_MATH_RENDER_AS_CODE = False +M_MATH_CACHE_FILE = "m.math.cache" From ab15dac0c5b44937a38c9c3aa88d831e5da810d7 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 19 Sep 2024 15:16:15 -0400 Subject: [PATCH 135/138] Don't generate HTML that we won't use Signed-off-by: Sara Damiano --- docs/Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Doxyfile b/docs/Doxyfile index 916295cae..9a269c934 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1348,7 +1348,7 @@ IGNORE_PREFIX = # If the GENERATE_HTML tag is set to YES, Doxygen will generate HTML output # The default value is: YES. -GENERATE_HTML = YES +GENERATE_HTML = NO # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of From b883d94e43c350dae78b333fa35b171fa28ae077 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 19 Sep 2024 16:36:15 -0400 Subject: [PATCH 136/138] Remove extra emphasized return types. Signed-off-by: Sara Damiano --- src/LogBuffer.h | 4 +- src/LoggerBase.h | 74 ++++++++++++------------ src/LoggerModem.h | 60 +++++++++---------- src/SensorBase.h | 30 +++++----- src/VariableArray.h | 18 +++--- src/VariableBase.h | 32 +++++----- src/dataPublisherBase.h | 12 ++-- src/modems/DigiXBee3GBypass.h | 2 +- src/modems/DigiXBeeCellularTransparent.h | 2 +- src/modems/DigiXBeeLTEBypass.h | 2 +- src/modems/DigiXBeeWifi.h | 2 +- src/publishers/DreamHostPublisher.h | 2 +- src/publishers/EnviroDIYPublisher.h | 12 ++-- src/publishers/UbidotsPublisher.h | 4 +- src/sensors/AOSongAM2315.h | 4 +- src/sensors/AnalogElecConductivity.h | 2 +- src/sensors/ApogeeSQ212.h | 2 +- src/sensors/AtlasParent.h | 10 ++-- src/sensors/AtlasScientificCO2.h | 2 +- src/sensors/AtlasScientificDO.h | 2 +- src/sensors/AtlasScientificEC.h | 2 +- src/sensors/BoschBME280.h | 4 +- src/sensors/BoschBMP3xx.h | 4 +- src/sensors/FreescaleMPL115A2.h | 2 +- src/sensors/GroPointParent.h | 6 +- src/sensors/KellerParent.h | 2 +- src/sensors/MaxBotixSonar.h | 4 +- src/sensors/MaximDS18.h | 6 +- src/sensors/MaximDS3231.h | 4 +- src/sensors/MeaSpecMS5803.h | 2 +- src/sensors/PaleoTerraRedox.h | 2 +- src/sensors/RainCounterI2C.h | 2 +- src/sensors/SDI12Sensors.h | 12 ++-- src/sensors/SensirionSHT4x.h | 4 +- src/sensors/TIINA219.h | 4 +- src/sensors/TallyCounterI2C.h | 2 +- src/sensors/YosemitechParent.h | 6 +- 37 files changed, 173 insertions(+), 173 deletions(-) diff --git a/src/LogBuffer.h b/src/LogBuffer.h index 7186024a6..c648dfd3e 100644 --- a/src/LogBuffer.h +++ b/src/LogBuffer.h @@ -109,7 +109,7 @@ class LogBuffer { * * @param record The record * - * @return **uint32_t** The record's timestamp. + * @return The record's timestamp. */ uint32_t getRecordTimestamp(int record); @@ -119,7 +119,7 @@ class LogBuffer { * @param record The record * @param variable The variable * - * @return **float** The variable's value. + * @return The variable's value. */ float getRecordValue(int record, uint8_t variable); diff --git a/src/LoggerBase.h b/src/LoggerBase.h index b1f6e2c73..dbf3b2123 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -167,7 +167,7 @@ class Logger { /** * @brief Get the Logger ID. * - * @return **const char\*** A pointer to the logger ID + * @return A pointer to the logger ID */ const char* getLoggerID() { return _loggerID; @@ -183,7 +183,7 @@ class Logger { /** * @brief Get the Logging Interval. * - * @return **uint16_t** The logging interval in minutes + * @return The logging interval in minutes */ uint16_t getLoggingInterval() { return _loggingIntervalMinutes; @@ -199,7 +199,7 @@ class Logger { /** * @brief Get the Sampling Feature UUID. * - * @return **const char\*** The sampling feature UUID + * @return The sampling feature UUID */ const char* getSamplingFeatureUUID() { return _samplingFeatureUUID; @@ -472,7 +472,7 @@ class Logger { /** * @brief Get the number of variables in the internal variable array object. * - * @return **uint8_t** The number of variables in the internal variable + * @return The number of variables in the internal variable * array object */ uint8_t getArrayVarCount(); @@ -482,7 +482,7 @@ class Logger { * position in the internal variable array object. * * @param position_i The position of the variable in the array. - * @return **String** The name of the parent sensor of that variable, if + * @return The name of the parent sensor of that variable, if * applicable. */ String getParentSensorNameAtI(uint8_t position_i); @@ -491,7 +491,7 @@ class Logger { * at the given position in the internal variable array object. * * @param position_i The position of the variable in the array. - * @return **String** The concatenated name and pin location of the parent + * @return The concatenated name and pin location of the parent * sensor of that variable, if applicable. */ String getParentSensorNameAndLocationAtI(uint8_t position_i); @@ -503,7 +503,7 @@ class Logger { * http://vocabulary.odm2.org/variablename/ * * @param position_i The position of the variable in the array. - * @return **String** The variable name + * @return The variable name */ String getVarNameAtI(uint8_t position_i); /** @@ -514,7 +514,7 @@ class Logger { * http://vocabulary.odm2.org/units/ * * @param position_i The position of the variable in the array. - * @return **String** The variable unit + * @return The variable unit */ String getVarUnitAtI(uint8_t position_i); /** @@ -522,7 +522,7 @@ class Logger { * the internal variable array object. * * @param position_i The position of the variable in the array. - * @return **String** The variable code + * @return The variable code */ String getVarCodeAtI(uint8_t position_i); /** @@ -530,7 +530,7 @@ class Logger { * variable array object. * * @param position_i The position of the variable in the array. - * @return **String** The variable UUID + * @return The variable UUID */ String getVarUUIDAtI(uint8_t position_i); /** @@ -538,7 +538,7 @@ class Logger { * the internal variable array object. * * @param position_i The position of the variable in the array. - * @return **float** The value of the variable as a float. + * @return The value of the variable as a float. */ float getValueAtI(uint8_t position_i); /** @@ -546,7 +546,7 @@ class Logger { * the internal variable array object. * * @param position_i The position of the variable in the array. - * @return **String** The value of the variable as a string with the correct + * @return The value of the variable as a string with the correct * number of significant figures. */ String getValueStringAtI(uint8_t position_i); @@ -556,7 +556,7 @@ class Logger { * * @param position_i The position of the variable in the array. * @param value The value to format. - * @return **String** The given value as a string with the correct number of + * @return The given value as a string with the correct number of * significant figures. */ String formatValueStringAtI(uint8_t position_i, float value); @@ -594,7 +594,7 @@ class Logger { * @brief Use the attahed loggerModem to synchronize the real-time clock * with NIST time servers. * - * @return **bool** True if clock synchronization was successful + * @return True if clock synchronization was successful */ bool syncRTC(); @@ -664,7 +664,7 @@ class Logger { /** * @brief Get the Logger Time Zone. * - * @return **int8_t** The timezone data is be saved to the SD card in. This + * @return The timezone data is be saved to the SD card in. This * is not be the same as the timezone of the real time clock. */ static int8_t getLoggerTimeZone(void); @@ -684,7 +684,7 @@ class Logger { * * @m_deprecated_since{0,22,4} * - * @return **int8_t** The timezone data is be saved to the SD card in. This + * @return The timezone data is be saved to the SD card in. This * is not be the same as the timezone of the real time clock. */ static int8_t getTimeZone(void); @@ -700,7 +700,7 @@ class Logger { /** * @brief Get the timezone of the real-time clock (RTC). * - * @return **int8_t** The timezone of the real-time clock (RTC) + * @return The timezone of the real-time clock (RTC) */ static int8_t getRTCTimeZone(void); @@ -720,7 +720,7 @@ class Logger { * @brief Get the offset between the built-in clock and the time zone * where the data is being recorded. * - * @return **int8_t** The offset between the built-in clock and the time + * @return The offset between the built-in clock and the time * zone where the data is being recorded. */ static int8_t getTZOffset(void); @@ -741,7 +741,7 @@ class Logger { * number of seconds from January 1, 1970 00:00:00) and correct it to the * logging time zone. * - * @return **uint32_t** The number of seconds from January 1, 1970 in the + * @return The number of seconds from January 1, 1970 in the * logging time zone. * * @m_deprecated_since{0,33,0} @@ -753,7 +753,7 @@ class Logger { * number of seconds from January 1, 1970 00:00:00) and correct it to the * logging time zone. * - * @return **uint32_t** The number of seconds from January 1, 1970 in the + * @return The number of seconds from January 1, 1970 in the * logging time zone. */ static uint32_t getNowLocalEpoch(void); @@ -763,7 +763,7 @@ class Logger { * the RTC (unix time, ie, the number of seconds from January 1, 1970 * 00:00:00 UTC) * - * @return **uint32_t** The number of seconds from 1970-01-01T00:00:00Z0000 + * @return The number of seconds from 1970-01-01T00:00:00Z0000 */ static uint32_t getNowUTCEpoch(void); /** @@ -783,7 +783,7 @@ class Logger { * object instance. * * @param epochTime The number of seconds since 1970. - * @return **DateTime** The equivalent DateTime + * @return The equivalent DateTime */ static DateTime dtFromEpoch(uint32_t epochTime); @@ -794,7 +794,7 @@ class Logger { * the LOGGER's offset as the time zone offset in the string. * * @param dt A DateTime object to convert - * @return **String** An ISO8601 formatted String. + * @return An ISO8601 formatted String. */ static String formatDateTime_ISO8601(DateTime& dt); @@ -805,7 +805,7 @@ class Logger { * the LOGGER's offset as the time zone offset in the string. * * @param epochTime The number of seconds since 1970. - * @return **String** An ISO8601 formatted String. + * @return An ISO8601 formatted String. */ static String formatDateTime_ISO8601(uint32_t epochTime); @@ -814,7 +814,7 @@ class Logger { * clock to the given time. * * @param UTCEpochSeconds The number of seconds since 1970 in UTC. - * @return **bool** True if the input timestamp passes sanity checks **and** + * @return True if the input timestamp passes sanity checks **and** * the clock has been successfully set. */ bool setRTClock(uint32_t UTCEpochSeconds); @@ -824,7 +824,7 @@ class Logger { * * To be sane the clock must be between 2020 and 2030. * - * @return **bool** True if the current time on the RTC passes sanity range + * @return True if the current time on the RTC passes sanity range * checking */ static bool isRTCSane(void); @@ -835,7 +835,7 @@ class Logger { * To be sane the clock must be between 2020 and 2025. * * @param epochTime The epoch time to be checked. - * @return **bool** True if the given time passes sanity range checking. + * @return True if the given time passes sanity range checking. */ static bool isRTCSane(uint32_t epochTime); @@ -854,7 +854,7 @@ class Logger { /** * @brief Check if the CURRENT time is an even interval of the logging rate * - * @return **bool** True if the current time on the RTC is an even interval + * @return True if the current time on the RTC is an even interval * of the logging rate. */ bool checkInterval(void); @@ -868,7 +868,7 @@ class Logger { * printing, etc) have the same timestamp even though the update routine may * take several (or many) seconds. * - * @return **bool** True if the marked time is an even interval of the + * @return True if the marked time is an even interval of the * logging rate. */ bool checkMarkedInterval(void); @@ -1038,7 +1038,7 @@ class Logger { * an auto-generated filename which is a concatenation of the logger id and * the date when the file was started. * - * @return **String** The name of the file data is currently being saved to. + * @return The name of the file data is currently being saved to. */ String getFileName(void) { return _fileName; @@ -1076,7 +1076,7 @@ class Logger { * @param filename The name of the file to create * @param writeDefaultHeader True to write a header to the file, default is * false - * @return **bool** True if the file was successfully created. + * @return True if the file was successfully created. */ bool createLogFile(String& filename, bool writeDefaultHeader = false); /** @@ -1090,7 +1090,7 @@ class Logger { * * @param writeDefaultHeader True to write a header to the file, default is * false - * @return **bool** True if the file was successfully created. + * @return True if the file was successfully created. */ bool createLogFile(bool writeDefaultHeader = false); @@ -1104,7 +1104,7 @@ class Logger { * * @param filename The name of the file to write to * @param rec The line to be written to the file - * @return **bool** True if the file was successfully accessed or created + * @return True if the file was successfully accessed or created * _and_ data appended to it. */ bool logToSD(String& filename, String& rec); @@ -1117,7 +1117,7 @@ class Logger { * modified and accessed timestamps of the file to the current time. * * @param rec The line to be written to the file - * @return **bool** True if the file was successfully accessed or created + * @return True if the file was successfully accessed or created * _and_ data appended to it. */ bool logToSD(String& rec); @@ -1130,7 +1130,7 @@ class Logger { * attempt to create the file and add a header to it. Set the modified and * accessed timestamps of the file to the current time. * - * @return **bool** True if the file was successfully accessed or created + * @return True if the file was successfully accessed or created * _and_ data appended to it. */ bool logToSD(void); @@ -1157,7 +1157,7 @@ class Logger { * We run this check before every communication with the SD card to prevent * hanging. * - * @return **bool** True if the SD card is ready + * @return True if the SD card is ready */ bool initializeSDCard(void); @@ -1185,7 +1185,7 @@ class Logger { * @param createFile True to create the file if it did not already exist * @param writeDefaultHeader True to add a header to the file if it is * created - * @return **bool** True if a file was successfully opened or created. + * @return True if a file was successfully opened or created. */ bool openFile(String& filename, bool createFile, bool writeDefaultHeader); /**@}*/ diff --git a/src/LoggerModem.h b/src/LoggerModem.h index d7c22470e..ccd456af6 100644 --- a/src/LoggerModem.h +++ b/src/LoggerModem.h @@ -361,7 +361,7 @@ class loggerModem { /** * @brief Get the modem name. * - * @return **String** The modem name + * @return The modem name */ String getModemName(void); @@ -370,7 +370,7 @@ class loggerModem { * * @note These values are polled for and cached in memory till needed * - * @return **String** The concatenated name, hardware version, firmware + * @return The concatenated name, hardware version, firmware * version, and serial number of the modem. * * @todo Implement this for modems other than the XBee WiFi @@ -383,7 +383,7 @@ class loggerModem { * This is used for operations that cannot happen in the modem constructor - * they must happen at run time, not at compile time. * - * @return **bool** True if setup was successful + * @return True if setup was successful */ virtual bool modemSetup(void); /** @@ -392,7 +392,7 @@ class loggerModem { * * @m_deprecated_since{0,24,1} * - * @return **bool** True if setup was successful + * @return True if setup was successful */ bool setup(void) { return modemSetup(); @@ -415,7 +415,7 @@ class loggerModem { * * For most modules, this function is created by the #MS_MODEM_WAKE macro. * - * @return **bool** True if the modem is responsive and ready for action. + * @return True if the modem is responsive and ready for action. */ virtual bool modemWake(void) = 0; /** @@ -423,7 +423,7 @@ class loggerModem { * * @m_deprecated_since{0,24,1} * - * @return **bool** True if wake was sucessful, modem should be ready to + * @return True if wake was sucessful, modem should be ready to * communicate */ bool wake(void) { @@ -445,7 +445,7 @@ class loggerModem { /** * @brief Request that the modem enter its lowest possible power state. * - * @return **bool** True if the modem has sucessfully entered low power + * @return True if the modem has sucessfully entered low power * state */ virtual bool modemSleep(void); @@ -457,7 +457,7 @@ class loggerModem { * This allows the modem to shut down all connections cleanly and do any * necessary internal housekeeping before stopping power. * - * @return **bool** True if the modem has sucessfully entered low power + * @return True if the modem has sucessfully entered low power * state _and_ then powered off */ virtual bool modemSleepPowerDown(void); @@ -469,7 +469,7 @@ class loggerModem { * * This should only be used if the modem is clearly non-responsive. * - * @return **bool** True if the reset succeeded and the modem should now be + * @return True if the reset succeeded and the modem should now be * responsive. False if the modem remains non-responsive either because the * reset failed to fix the communication issue or because a reset is not * possible with the current pin/modem configuration. @@ -534,7 +534,7 @@ class loggerModem { * @param maxConnectionTime The maximum length of time in milliseconds to * wait for network registration and data sconnection. Defaults to 50,000ms * (50s). - * @return **bool** True if EPS or GPRS data connection has been + * @return True if EPS or GPRS data connection has been * established. False if the modem wasunresponsive, unable to register with * the cellular network, or unable to establish a EPS or GPRS connection. */ @@ -554,7 +554,7 @@ class loggerModem { * * @note The return is the number of seconds since Jan 1, 1970 IN UTC * - * @return **uint32_t** The number of seconds since Jan 1, 1970 IN UTC + * @return The number of seconds since Jan 1, 1970 IN UTC */ virtual uint32_t getNISTTime(void) = 0; /**@}*/ @@ -581,7 +581,7 @@ class loggerModem { * signal strength indicator * @param percent A reference to an int16_t which will be set with the * "percent" signal strength - * @return **bool** True indicates that the communication with the modem was + * @return True indicates that the communication with the modem was * successful and the values referenced by the pointers should be valid. */ virtual bool getModemSignalQuality(int16_t& rssi, int16_t& percent) = 0; @@ -598,7 +598,7 @@ class loggerModem { * @param milliVolts A reference to an uint16_t which will be set with the * current battery voltage in mV - this may or may not be a valid value * depending on the module and breakout. - * @return **bool** True indicates that the communication with the modem was + * @return True indicates that the communication with the modem was * successful and the values referenced by the pointers should be valid. */ virtual bool getModemBatteryStats(int8_t& chargeState, int8_t& percent, @@ -606,7 +606,7 @@ class loggerModem { /** * @brief Get the current temperature provided by the modem module. * - * @return **float** The temperature in degrees Celsius + * @return The temperature in degrees Celsius */ virtual float getModemChipTemperature(void) = 0; @@ -658,7 +658,7 @@ class loggerModem { * @brief Query the modem for signal quality, battery, and temperature * information and store the values to the static internal variables. * - * @return **bool** True indicates that the communication with the modem + * @return True indicates that the communication with the modem * was successful and the values of the internal static variables should * be valid. */ @@ -681,7 +681,7 @@ class loggerModem { * * @note Does NOT query the modem for a new value. * - * @return **float** The stored RSSI + * @return The stored RSSI */ static float getModemRSSI(); @@ -690,7 +690,7 @@ class loggerModem { * * @note Does NOT query the modem for a new value. * - * @return **float** The stored signal strength + * @return The stored signal strength */ static float getModemSignalPercent(); @@ -699,7 +699,7 @@ class loggerModem { * * @note Does NOT query the modem for a new value. * - * @return **float** The stored signal percent + * @return The stored signal percent */ static float getModemBatteryChargeState(); @@ -708,7 +708,7 @@ class loggerModem { * * @note Does NOT query the modem for a new value. * - * @return **float** The stored battery charge percent + * @return The stored battery charge percent */ static float getModemBatteryChargePercent(); @@ -717,7 +717,7 @@ class loggerModem { * * @note Does NOT query the modem for a new value. * - * @return **float** The stored battery voltage in mV + * @return The stored battery voltage in mV */ static float getModemBatteryVoltage(); @@ -726,7 +726,7 @@ class loggerModem { * * @note Does NOT query the modem for a new value. * - * @return **float** The stored temperature in degrees Celsius + * @return The stored temperature in degrees Celsius */ static float getModemTemperature(); /**@}*/ @@ -743,7 +743,7 @@ class loggerModem { * The RSSI is estimated from a look-up assuming no noise. * * @param csq A "CSQ" (0-31) signal qualilty - * @return **int16_t** An RSSI in dBm, making assumptions about the + * @return An RSSI in dBm, making assumptions about the * conversion */ static int16_t getRSSIFromCSQ(int16_t csq); @@ -753,14 +753,14 @@ class loggerModem { * The percent is grabbed from a look-up. * * @param csq A "CSQ" (0-31) signal qualilty - * @return **int16_t** The percent of maximum signal strength. + * @return The percent of maximum signal strength. */ static int16_t getPctFromCSQ(int16_t csq); /** * @brief Get signal percent from CSQ. * * @param rssi The RSSI in dBm. - * @return **int16_t** The estimated percent of maximum signal strength. + * @return The estimated percent of maximum signal strength. */ static int16_t getPctFromRSSI(int16_t rssi); /**@}*/ @@ -793,7 +793,7 @@ class loggerModem { /** * @brief Check whether there is an active internet connection available. * - * @return **bool** True if there is an active data connection to the + * @return True if there is an active data connection to the * internet. */ virtual bool isInternetAvailable(void) = 0; @@ -802,7 +802,7 @@ class loggerModem { * specific module, as opposed to the parts of setup that are common to all * modem modules. * - * @return **bool** True if the unique part of the sleep function ran + * @return True if the unique part of the sleep function ran * sucessfully. */ virtual bool modemSleepFxn(void) = 0; @@ -811,7 +811,7 @@ class loggerModem { * a specific module, as opposed to the parts of setup that are common to * all modem modules. * - * @return **bool** True if the unique part of the wake function ran + * @return True if the unique part of the wake function ran * sucessfully - does _NOT_ indicate that the modem is now responsive. */ virtual bool modemWakeFxn(void) = 0; @@ -823,7 +823,7 @@ class loggerModem { * For most modules, this function is created by the #MS_MODEM_EXTRA_SETUP * macro which runs the TinyGSM modem init() and client init() functions. * - * @return **bool** True if the extra setup succeeded. + * @return True if the extra setup succeeded. */ virtual bool extraModemSetup(void) = 0; /** @@ -845,7 +845,7 @@ class loggerModem { * and am using AT commands to sleep. This *should* keep everything lined * up. * - * @return **bool** True if the modem is already awake. + * @return True if the modem is already awake. */ virtual bool isModemAwake(void) = 0; /**@}*/ @@ -860,7 +860,7 @@ class loggerModem { * so there is no need to close it * * @param nistBytes 4 bytes from NIST - * @return **uint32_t** the number of seconds since January 1, 1970 00:00:00 + * @return the number of seconds since January 1, 1970 00:00:00 * UTC */ static uint32_t parseNISTBytes(byte nistBytes[4]); diff --git a/src/SensorBase.h b/src/SensorBase.h index 55ef4c30c..3a7503db0 100644 --- a/src/SensorBase.h +++ b/src/SensorBase.h @@ -126,26 +126,26 @@ class Sensor { * @note This is NOT the position of the sensor in the environment, merely * how it is attached to the mcu. * - * @return **String** Text describing how the sensor is attached to the mcu. + * @return Text describing how the sensor is attached to the mcu. */ virtual String getSensorLocation(void); /** * @brief Get the name of the sensor. * - * @return **String** The sensor name as given in the constructor. + * @return The sensor name as given in the constructor. */ virtual String getSensorName(void); /** * @brief Concatentate and returns the name and location of the sensor. * - * @return **String** A concatenation of the sensor name and its "location" + * @return A concatenation of the sensor name and its "location" * - how it is connected to the mcu. */ String getSensorNameAndLocation(void); /** * @brief Get the pin number controlling sensor power. * - * @return **int8_t** The pin on the mcu controlling power to the sensor. + * @return The pin on the mcu controlling power to the sensor. */ virtual int8_t getPowerPin(void); @@ -161,7 +161,7 @@ class Sensor { /** * @brief Get the number of measurements to average. * - * @return **uint8_t** The number of readings to take and average to create + * @return The number of readings to take and average to create * a result from the sensor. * * @copydetails _measurementsToAverage @@ -226,7 +226,7 @@ class Sensor { * This sets the pin modes of the _powerPin and _dataPin, updates * #_sensorStatus, and returns true. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ virtual bool setup(void); @@ -247,7 +247,7 @@ class Sensor { * used. To work with many sensors together, use the VariableArray class * which optimizes the timing and waits for many sensors working together. * - * @return **bool** True if all steps of the sensor update completed + * @return True if all steps of the sensor update completed * successfully. */ virtual bool update(void); @@ -277,7 +277,7 @@ class Sensor { * * @note This does NOT include any wait for sensor readiness. * - * @return **bool** True if the wake function completed successfully. + * @return True if the wake function completed successfully. */ virtual bool wake(void); /** @@ -287,7 +287,7 @@ class Sensor { * * @note This does NOT power down the sensor! * - * @return **bool** True if the sleep function completed successfully. + * @return True if the sleep function completed successfully. */ virtual bool sleep(void); @@ -300,7 +300,7 @@ class Sensor { * @note This function does NOT include any waiting for the sensor to be * warmed up or stable! * - * @return **bool** True if the start measurement function completed + * @return True if the start measurement function completed * successfully. */ virtual bool startSingleMeasurement(void); @@ -317,7 +317,7 @@ class Sensor { * @note This function does NOT include any waiting for the sensor complete * a measurement. * - * @return **bool** True if the function completed successfully. + * @return True if the function completed successfully. */ virtual bool addSingleMeasurementResult(void) = 0; @@ -382,7 +382,7 @@ class Sensor { * @brief Check if the #_powerPin is currently high. * * @param debug True to output the result to the debugging Serial - * @return **bool** True indicates the #_powerPin is currently `HIGH`. + * @return True indicates the #_powerPin is currently `HIGH`. */ bool checkPowerOn(bool debug = false); /** @@ -390,7 +390,7 @@ class Sensor { * receiving power and being ready to respond to logger commands. * * @param debug True to output the result to the debugging Serial - * @return **bool** True indicates that enough time has passed that the + * @return True indicates that enough time has passed that the * sensor should be ready to respond to commands. * * @note A true response does _NOT_ indicate that the sensor will respond to @@ -408,7 +408,7 @@ class Sensor { * being awoken/activated and being ready to output stable values. * * @param debug True to output the result to the debugging Serial - * @return **bool** True indicates that enough time has passed that the + * @return True indicates that enough time has passed that the * sensor should have stabilized. * * @note A true response does _NOT_ indicate that the sensor is now giving @@ -428,7 +428,7 @@ class Sensor { * is expected to be complete. * * @param debug True to output the result to the debugging Serial - * @return **bool** True indicates that enough time has passed the + * @return True indicates that enough time has passed the * measurement should have completed * * @note A true response does _NOT_ indicate that the sensor will now diff --git a/src/VariableArray.h b/src/VariableArray.h index 087b9f640..ec5f33f51 100644 --- a/src/VariableArray.h +++ b/src/VariableArray.h @@ -148,7 +148,7 @@ class VariableArray { /** * @brief Get the count of variables in the variable array * - * @return **uint8_t** the number of variables + * @return the number of variables */ uint8_t getVariableCount(void) { return _variableCount; @@ -157,7 +157,7 @@ class VariableArray { /** * @brief Get the number of calculated variables * - * @return **uint8_t** The number of calculated (ie, not measured by a + * @return The number of calculated (ie, not measured by a * sensor) variables */ uint8_t getCalculatedVariableCount(void); @@ -170,7 +170,7 @@ class VariableArray { * This will often be different from the number of variables because many * sensors can return multiple variables. * - * @return **uint8_t** The number of sensors + * @return The number of sensors */ uint8_t getSensorCount(void); @@ -194,7 +194,7 @@ class VariableArray { * respond to its setup command, the command is called 5 times in attempt to * make a connection. If all sensors are set up successfully, returns true. * - * @return **bool** True indicates all sensors have been set up + * @return True indicates all sensors have been set up * successfully. */ bool setupSensors(void); @@ -212,7 +212,7 @@ class VariableArray { * Runs the wake sensor function for each unique sensor. Repeatedly checks * each sensor's readiness state to optimize timing. * - * @return **bool** True if all wake functions were run successfully. + * @return True if all wake functions were run successfully. */ bool sensorsWake(void); @@ -221,7 +221,7 @@ class VariableArray { * * Runs the sleep sensor function for each unique sensor. * - * @return **bool** True if all sleep functions were run successfully. + * @return True if all sleep functions were run successfully. */ bool sensorsSleep(void); @@ -238,7 +238,7 @@ class VariableArray { * overall success. Does NOT return any values. Repeatedly checks each * sensor's readiness state to optimize timing. * - * @return **bool** True if all steps of the update succeeded. + * @return True if all steps of the update succeeded. */ bool updateAllSensors(void); @@ -252,7 +252,7 @@ class VariableArray { * values. Repeatedly checks each sensor's readiness state to optimize * timing. * - * @return **bool** True if all steps of the update succeeded. + * @return True if all steps of the update succeeded. */ bool completeUpdate(void); @@ -299,7 +299,7 @@ class VariableArray { * @brief Count the maximum number of measurements needed from a single * sensor for the requested averaging * - * @return *uint8_t* The number of measurements needed. + * @return The number of measurements needed. */ uint8_t countMaxToAverage(void); /** diff --git a/src/VariableBase.h b/src/VariableBase.h index ff078e7da..6bf16e698 100644 --- a/src/VariableBase.h +++ b/src/VariableBase.h @@ -150,7 +150,7 @@ class Variable { * Supercedes any value supplied in the constructor. * @param customVarCode A custom code for the variable. Supercedes * any value supplied in the constructor. - * @return Variable A pointer to the variable object + * @return A pointer to the variable object */ Variable* begin(Sensor* parentSense, const char* uuid, const char* customVarCode); @@ -161,7 +161,7 @@ class Variable { * Sensor supplied in the constructor. * @param uuid A universally unique identifier for the variable. * Supercedes any value supplied in the constructor. - * @return Variable A pointer to the variable object + * @return A pointer to the variable object */ Variable* begin(Sensor* parentSense, const char* uuid); /** @@ -169,7 +169,7 @@ class Variable { * * @param parentSense The Sensor object supplying values. Supercedes any * Sensor supplied in the constructor. - * @return Variable A pointer to the variable object + * @return A pointer to the variable object */ Variable* begin(Sensor* parentSense); @@ -188,7 +188,7 @@ class Variable { * supplied in the constructor. * @param uuid A universally unique identifier for the variable. * Supercedes any value supplied in the constructor. - * @return Variable A pointer to the variable object + * @return A pointer to the variable object */ Variable* begin(float (*calcFxn)(), uint8_t decimalResolution, const char* varName, const char* varUnit, @@ -206,7 +206,7 @@ class Variable { * vocabulary. Supercedes any value supplied in the constructor. * @param varCode A custom code for the variable. Supercedes any value * supplied in the constructor. - * @return Variable A pointer to the variable object + * @return A pointer to the variable object */ Variable* begin(float (*calcFxn)(), uint8_t decimalResolution, const char* varName, const char* varUnit, @@ -239,7 +239,7 @@ class Variable { * * This is a helper needed for dealing with variables in arrays * - * @return **String** The parent sensor name + * @return The parent sensor name */ String getParentSensorName(void); /** @@ -247,7 +247,7 @@ class Variable { * * This is a helper needed for dealing with variables in arrays * - * @return **String** The parent sensor's concatentated name and location. + * @return The parent sensor's concatentated name and location. */ String getParentSensorNameAndLocation(void); @@ -262,7 +262,7 @@ class Variable { /** * @brief Get the variable's resolution - in decimal places * - * @return **uint8_t** the variable resolution + * @return the variable resolution */ uint8_t getResolution(void); /** @@ -274,7 +274,7 @@ class Variable { /** * @brief Get the variable name * - * @return **String** The variable name + * @return The variable name */ String getVarName(void); /** @@ -290,7 +290,7 @@ class Variable { /** * @brief Get the variable unit * - * @return **String** The variable unit + * @return The variable unit */ String getVarUnit(void); /** @@ -306,7 +306,7 @@ class Variable { /** * @brief Get the customized code for the variable * - * @return **String** The customized code for the variable + * @return The customized code for the variable */ String getVarCode(void); /** @@ -320,7 +320,7 @@ class Variable { /** * @brief Get the customized code for the variable * - * @return **String** The customized code for the variable + * @return The customized code for the variable */ String getVarUUID(void); /** @@ -332,7 +332,7 @@ class Variable { /** * @brief Verify the the UUID is correctly formatted * - * @return **bool** True if the UUID is correctly formatted. + * @return True if the UUID is correctly formatted. * * @note This only checks the _format_ of the UUID. It does not in any way * indicate that the value of the UUID is correct. @@ -344,7 +344,7 @@ class Variable { * * @param updateValue True to ask the parent sensor to measure and return a * new value. Default is false. - * @return **float** The current value of the variable + * @return The current value of the variable */ float getValue(bool updateValue = false); /** @@ -353,7 +353,7 @@ class Variable { * * @param updateValue True to ask the parent sensor to measure and return a * new value. Default is false. - * @return **String** The current value of the variable + * @return The current value of the variable */ String getValueString(bool updateValue = false); /** @@ -361,7 +361,7 @@ class Variable { * correct decimal resolution * * @param value value to format - * @return **String** The formatted value of the variable + * @return The formatted value of the variable */ String formatValueString(float value); diff --git a/src/dataPublisherBase.h b/src/dataPublisherBase.h index 4ad472351..c0a16f3b6 100644 --- a/src/dataPublisherBase.h +++ b/src/dataPublisherBase.h @@ -163,7 +163,7 @@ class dataPublisher { * @brief Get the destination for published data - generally the host name * of the data receiver. * - * @return **String** The URL or HOST to receive published data + * @return The URL or HOST to receive published data */ virtual String getEndpoint(void) = 0; @@ -187,7 +187,7 @@ class dataPublisher { * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance * @param forceFlush Ask the publisher to flush buffered data immediately. - * @return **int16_t** The result of publishing data. May be an http + * @return The result of publishing data. May be an http * response code or a result code from PubSubClient. */ virtual int16_t publishData(Client* outClient, bool forceFlush = false) = 0; @@ -201,7 +201,7 @@ class dataPublisher { * * @param forceFlush Ask the publisher to flush buffered data immediately. * - * @return **int16_t** The result of publishing data. May be an http + * @return The result of publishing data. May be an http * response code or a result code from PubSubClient. */ virtual int16_t publishData(bool forceFlush = false); @@ -215,7 +215,7 @@ class dataPublisher { * @param outClient An Arduino client instance to use to print data to. * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance - * @return **int16_t** The result of publishing data. May be an http + * @return The result of publishing data. May be an http * response code or a result code from PubSubClient. */ virtual int16_t sendData(Client* outClient); @@ -225,7 +225,7 @@ class dataPublisher { * * @m_deprecated_since{0,22,5} * - * @return **int16_t** The result of publishing data. May be an http + * @return The result of publishing data. May be an http * response code or a result code from PubSubClient. */ virtual int16_t sendData(); @@ -235,7 +235,7 @@ class dataPublisher { * explanation. * * @param state A result code returned by a PubSubClient action - * @return **String** The meaning of the code + * @return The meaning of the code */ String parseMQTTState(int state); diff --git a/src/modems/DigiXBee3GBypass.h b/src/modems/DigiXBee3GBypass.h index 4dfe8472f..36cfb65da 100644 --- a/src/modems/DigiXBee3GBypass.h +++ b/src/modems/DigiXBee3GBypass.h @@ -162,7 +162,7 @@ class DigiXBee3GBypass : public DigiXBee { * bypass), enables pin sleep, sets the DIO pins to the expected functions, * and reboots the modem to ensure all settings are applied. * - * @return **bool** True if the extra setup succeeded. + * @return True if the extra setup succeeded. */ bool extraModemSetup(void) override; bool isModemAwake(void) override; diff --git a/src/modems/DigiXBeeCellularTransparent.h b/src/modems/DigiXBeeCellularTransparent.h index c7e67aea6..1b626bff4 100644 --- a/src/modems/DigiXBeeCellularTransparent.h +++ b/src/modems/DigiXBeeCellularTransparent.h @@ -198,7 +198,7 @@ class DigiXBeeCellularTransparent : public DigiXBee { * bypass), enables pin sleep, sets the DIO pins to the expected functions, * and reboots the modem to ensure all settings are applied. * - * @return **bool** True if the extra setup succeeded. + * @return True if the extra setup succeeded. */ bool extraModemSetup(void) override; bool isModemAwake(void) override; diff --git a/src/modems/DigiXBeeLTEBypass.h b/src/modems/DigiXBeeLTEBypass.h index 7020e125f..a019ddb51 100644 --- a/src/modems/DigiXBeeLTEBypass.h +++ b/src/modems/DigiXBeeLTEBypass.h @@ -177,7 +177,7 @@ class DigiXBeeLTEBypass : public DigiXBee { * bypass), enables pin sleep, sets the DIO pins to the expected functions, * and reboots the modem to ensure all settings are applied. * - * @return **bool** True if the extra setup succeeded. + * @return True if the extra setup succeeded. */ bool extraModemSetup(void) override; bool isModemAwake(void) override; diff --git a/src/modems/DigiXBeeWifi.h b/src/modems/DigiXBeeWifi.h index dd4e4a368..f1abd75d7 100644 --- a/src/modems/DigiXBeeWifi.h +++ b/src/modems/DigiXBeeWifi.h @@ -173,7 +173,7 @@ class DigiXBeeWifi : public DigiXBee { * bypass), enables pin sleep, sets the DIO pins to the expected functions, * and reboots the modem to ensure all settings are applied. * - * @return **bool** True if the extra setup succeeded. + * @return True if the extra setup succeeded. */ bool extraModemSetup(void) override; bool isModemAwake(void) override; diff --git a/src/publishers/DreamHostPublisher.h b/src/publishers/DreamHostPublisher.h index 243e46038..f07e9c39f 100644 --- a/src/publishers/DreamHostPublisher.h +++ b/src/publishers/DreamHostPublisher.h @@ -133,7 +133,7 @@ class DreamHostPublisher : public dataPublisher { * single TinyGSM modem instance * @param forceFlush Ask the publisher to flush buffered data immediately. * - * @return **int16_t** The http status code of the response. + * @return The http status code of the response. */ int16_t publishData(Client* outClient, bool forceFlush = false) override; diff --git a/src/publishers/EnviroDIYPublisher.h b/src/publishers/EnviroDIYPublisher.h index 32e2cc45c..5d351dda9 100644 --- a/src/publishers/EnviroDIYPublisher.h +++ b/src/publishers/EnviroDIYPublisher.h @@ -113,7 +113,7 @@ class EnviroDIYPublisher : public dataPublisher { /** * @brief Get the EnviroDIY/Monitor My Watershed web host * - * @return **String** The EnviroDIY/Monitor My Watershed web host + * @return The EnviroDIY/Monitor My Watershed web host */ String getHost(void); @@ -127,7 +127,7 @@ class EnviroDIYPublisher : public dataPublisher { /** * @brief Get the EnviroDIY/Monitor My Watershed API path * - * @return **String** The EnviroDIY/Monitor My Watershed API path + * @return The EnviroDIY/Monitor My Watershed API path */ String getPath(void); /** @@ -140,7 +140,7 @@ class EnviroDIYPublisher : public dataPublisher { /** * @brief Get the EnviroDIY/Monitor My Watershed API port * - * @return **int** The EnviroDIY/Monitor My Watershed API port + * @return The EnviroDIY/Monitor My Watershed API port */ int getPort(void); /** @@ -162,7 +162,7 @@ class EnviroDIYPublisher : public dataPublisher { /** * @brief Calculates how long the outgoing JSON will be * - * @return uint16_t The number of characters in the JSON object. + * @return The number of characters in the JSON object. */ uint16_t calculateJsonSize(); @@ -207,7 +207,7 @@ class EnviroDIYPublisher : public dataPublisher { * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance * @param forceFlush Ask the publisher to flush buffered data immediately. - * @return **int16_t** The http status code of the response. + * @return The http status code of the response. */ int16_t publishData(Client* outClient, bool forceFlush = false) override; @@ -245,7 +245,7 @@ class EnviroDIYPublisher : public dataPublisher { * @brief Transmit data from the data buffer to an external site * * @param outClient The client to publish the data over - * @return **int16_t** The HTTP response code from the publish attempt + * @return The HTTP response code from the publish attempt * * @note A 504 will be returned automatically if the server does not * respond within 30 seconds. diff --git a/src/publishers/UbidotsPublisher.h b/src/publishers/UbidotsPublisher.h index 5b39270bb..fd680a813 100644 --- a/src/publishers/UbidotsPublisher.h +++ b/src/publishers/UbidotsPublisher.h @@ -124,7 +124,7 @@ class UbidotsPublisher : public dataPublisher { /** * @brief Calculates how long the outgoing JSON will be * - * @return uint16_t The number of characters in the JSON object. + * @return The number of characters in the JSON object. */ uint16_t calculateJsonSize(); @@ -165,7 +165,7 @@ class UbidotsPublisher : public dataPublisher { * Allows the use of any type of client and multiple clients tied to a * single TinyGSM modem instance * @param forceFlush Ask the publisher to flush buffered data immediately. - * @return **int16_t** The http status code of the response. + * @return The http status code of the response. */ int16_t publishData(Client* outClient, bool forceFlush) override; diff --git a/src/sensors/AOSongAM2315.h b/src/sensors/AOSongAM2315.h index 283e1b6ad..c3a7c7414 100644 --- a/src/sensors/AOSongAM2315.h +++ b/src/sensors/AOSongAM2315.h @@ -213,7 +213,7 @@ class AOSongAM2315 : public Sensor { /** * @brief Report the I2C address of the AM2315 - which is always 0xB8. * - * @return **String** Text describing how the sensor is attached to the mcu. + * @return Text describing how the sensor is attached to the mcu. */ String getSensorLocation(void) override; @@ -225,7 +225,7 @@ class AOSongAM2315 : public Sensor { * and modes for I2C), and updates the #_sensorStatus. No sensor power is * required. * - * @return **bool** True if the setup was successful. For the AOSong AM2315 + * @return True if the setup was successful. For the AOSong AM2315 * the result will always be true. */ bool setup(void) override; diff --git a/src/sensors/AnalogElecConductivity.h b/src/sensors/AnalogElecConductivity.h index 800b398d8..4d62a2431 100644 --- a/src/sensors/AnalogElecConductivity.h +++ b/src/sensors/AnalogElecConductivity.h @@ -359,7 +359,7 @@ class AnalogElecConductivity : public Sensor { /** * @brief Report the sensor info. * - * @return **String** Text describing how the sensor is attached to the mcu. + * @return Text describing how the sensor is attached to the mcu. */ String getSensorLocation(void) override; diff --git a/src/sensors/ApogeeSQ212.h b/src/sensors/ApogeeSQ212.h index 8bfc96dc6..f657013fd 100644 --- a/src/sensors/ApogeeSQ212.h +++ b/src/sensors/ApogeeSQ212.h @@ -270,7 +270,7 @@ class ApogeeSQ212 : public Sensor { * @brief Report the I1C address of the ADS and the channel that the SQ-212 * is attached to. * - * @return **String** Text describing how the sensor is attached to the mcu. + * @return Text describing how the sensor is attached to the mcu. */ String getSensorLocation(void) override; diff --git a/src/sensors/AtlasParent.h b/src/sensors/AtlasParent.h index e872f3204..1c3a8e129 100644 --- a/src/sensors/AtlasParent.h +++ b/src/sensors/AtlasParent.h @@ -172,7 +172,7 @@ class AtlasParent : public Sensor { /** * @brief Return the I2C address of the EZO circuit. * - * @return **String** Text describing how the sensor is attached to the mcu. + * @return Text describing how the sensor is attached to the mcu. */ String getSensorLocation(void) override; @@ -184,7 +184,7 @@ class AtlasParent : public Sensor { * and modes for I2C), and updates the #_sensorStatus. No sensor power is * required. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; @@ -199,7 +199,7 @@ class AtlasParent : public Sensor { * This also un-sets the #_millisSensorActivated timestamp (sets it to 0). * This does NOT power down the sensor! * - * @return **bool** True if the sleep function completed successfully. + * @return True if the sleep function completed successfully. */ bool sleep(void) override; @@ -211,7 +211,7 @@ class AtlasParent : public Sensor { * @note This function does NOT include any waiting for the sensor to be * warmed up or stable! * - * @return **bool** True if the start measurement function completed + * @return True if the start measurement function completed * successfully. */ bool startSingleMeasurement(void) override; @@ -243,7 +243,7 @@ class AtlasParent : public Sensor { * unavailable. * * @param timeout The maximum amout of time to wait in ms. - * @return **bool** True processing completed and a status code was returned + * @return True processing completed and a status code was returned * within the wait period. */ bool waitForProcessing(uint32_t timeout = 1000L); diff --git a/src/sensors/AtlasScientificCO2.h b/src/sensors/AtlasScientificCO2.h index fe3815fcf..4241cc6a6 100644 --- a/src/sensors/AtlasScientificCO2.h +++ b/src/sensors/AtlasScientificCO2.h @@ -234,7 +234,7 @@ class AtlasScientificCO2 : public AtlasParent { * circuit to report all possible measurement parameters, and sets the * status bit if successful. The circuit must be powered for setup. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; }; diff --git a/src/sensors/AtlasScientificDO.h b/src/sensors/AtlasScientificDO.h index d9c40f23f..0c037a3ae 100644 --- a/src/sensors/AtlasScientificDO.h +++ b/src/sensors/AtlasScientificDO.h @@ -242,7 +242,7 @@ class AtlasScientificDO : public AtlasParent { * circuit to report all possible measurement parameters, and sets the * status bit if successful. The circuit must be powered for setup. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; }; diff --git a/src/sensors/AtlasScientificEC.h b/src/sensors/AtlasScientificEC.h index 0bcb19001..67203c2da 100644 --- a/src/sensors/AtlasScientificEC.h +++ b/src/sensors/AtlasScientificEC.h @@ -305,7 +305,7 @@ class AtlasScientificEC : public AtlasParent { * circuit to report all possible measurement parameters, and sets the * status bit if successful. The circuit must be powered for setup. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; }; diff --git a/src/sensors/BoschBME280.h b/src/sensors/BoschBME280.h index fd0003d46..5da283c12 100644 --- a/src/sensors/BoschBME280.h +++ b/src/sensors/BoschBME280.h @@ -322,7 +322,7 @@ class BoschBME280 : public Sensor { * * @note This does NOT include any wait for sensor readiness. * - * @return **bool** True if the wake function completed successfully. + * @return True if the wake function completed successfully. */ bool wake(void) override; /** @@ -333,7 +333,7 @@ class BoschBME280 : public Sensor { * calibration coefficients from the BME280, and updates the #_sensorStatus. * The BME280 must be powered for setup. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; /** diff --git a/src/sensors/BoschBMP3xx.h b/src/sensors/BoschBMP3xx.h index de4e351a1..6ab004346 100644 --- a/src/sensors/BoschBMP3xx.h +++ b/src/sensors/BoschBMP3xx.h @@ -443,7 +443,7 @@ class BoschBMP3xx : public Sensor { * * @note This does NOT include any wait for sensor readiness. * - * @return **bool** True if the wake function completed successfully. + * @return True if the wake function completed successfully. */ bool wake(void) override; /** @@ -454,7 +454,7 @@ class BoschBMP3xx : public Sensor { * calibration coefficients from the BMP3xx, and updates the #_sensorStatus. * The BMP3xx must be powered for setup. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; /** diff --git a/src/sensors/FreescaleMPL115A2.h b/src/sensors/FreescaleMPL115A2.h index 08711308d..77ff5865b 100644 --- a/src/sensors/FreescaleMPL115A2.h +++ b/src/sensors/FreescaleMPL115A2.h @@ -224,7 +224,7 @@ class FreescaleMPL115A2 : public Sensor { * powered for setup. This doesn't return anything to indicate failure or * success, we just have to hope it worked. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; /** diff --git a/src/sensors/GroPointParent.h b/src/sensors/GroPointParent.h index 069a3c43e..235d432e7 100644 --- a/src/sensors/GroPointParent.h +++ b/src/sensors/GroPointParent.h @@ -165,7 +165,7 @@ class GroPointParent : public Sensor { * updates the #_sensorStatus. No sensor power is required. This will * always return true. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; /** @@ -177,7 +177,7 @@ class GroPointParent : public Sensor { * * @note This does NOT include any wait for sensor readiness. * - * @return **bool** True if the wake function completed successfully. + * @return True if the wake function completed successfully. */ bool wake(void) override; /** @@ -186,7 +186,7 @@ class GroPointParent : public Sensor { * This also un-sets the #_millisSensorActivated timestamp (sets it to 0). * This does NOT power down the sensor! * - * @return **bool** True if the sleep function completed successfully. + * @return True if the sleep function completed successfully. */ bool sleep(void) override; diff --git a/src/sensors/KellerParent.h b/src/sensors/KellerParent.h index ad048a3fd..e6d924615 100644 --- a/src/sensors/KellerParent.h +++ b/src/sensors/KellerParent.h @@ -242,7 +242,7 @@ class KellerParent : public Sensor { * updates the #_sensorStatus. No sensor power is required. This will * always return true. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; diff --git a/src/sensors/MaxBotixSonar.h b/src/sensors/MaxBotixSonar.h index 987e53084..84163d44f 100644 --- a/src/sensors/MaxBotixSonar.h +++ b/src/sensors/MaxBotixSonar.h @@ -228,7 +228,7 @@ class MaxBotixSonar : public Sensor { * timeout for modbus and updates the #_sensorStatus. No sensor power is * required. This will always return true. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; /** @@ -243,7 +243,7 @@ class MaxBotixSonar : public Sensor { * * @note This does NOT include any wait for sensor readiness. * - * @return **bool** True if the wake function completed successfully. + * @return True if the wake function completed successfully. */ bool wake(void) override; diff --git a/src/sensors/MaximDS18.h b/src/sensors/MaximDS18.h index 1a85c800c..d3a6830b9 100644 --- a/src/sensors/MaximDS18.h +++ b/src/sensors/MaximDS18.h @@ -229,7 +229,7 @@ class MaximDS18 : public Sensor { * operating in ASYNC mode and updates the #_sensorStatus. The sensor must * be powered for setup. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; /** @@ -245,7 +245,7 @@ class MaximDS18 : public Sensor { * @note This function does NOT include any waiting for the sensor to be * warmed up or stable! * - * @return **bool** True if the start measurement function completed + * @return True if the start measurement function completed * successfully. successfully. */ bool startSingleMeasurement(void) override; @@ -279,7 +279,7 @@ class MaximDS18 : public Sensor { * @brief Turns the address into a printable string * * @param OneWireAddress The one wire address as a DeviceAddress object - * @return *String* A pretty string version of the OneWire device address. + * @return A pretty string version of the OneWire device address. */ String makeAddressString(DeviceAddress OneWireAddress); }; diff --git a/src/sensors/MaximDS3231.h b/src/sensors/MaximDS3231.h index 6532866f2..bce87d6b5 100644 --- a/src/sensors/MaximDS3231.h +++ b/src/sensors/MaximDS3231.h @@ -175,7 +175,7 @@ class MaximDS3231 : public Sensor { * the RTC. The clock should be continuously powered, so we never need to * worry about power up. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; @@ -187,7 +187,7 @@ class MaximDS3231 : public Sensor { * @note This function does NOT include any waiting for the sensor to be * warmed up or stable! * - * @return **bool** True if the start measurement function completed + * @return True if the start measurement function completed * successfully. successfully. */ bool startSingleMeasurement(void) override; diff --git a/src/sensors/MeaSpecMS5803.h b/src/sensors/MeaSpecMS5803.h index 3c5fbfee6..b2ddb35a4 100644 --- a/src/sensors/MeaSpecMS5803.h +++ b/src/sensors/MeaSpecMS5803.h @@ -240,7 +240,7 @@ class MeaSpecMS5803 : public Sensor { * return anything to indicate failure or success, we just have to hope it * succeeded. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; /** diff --git a/src/sensors/PaleoTerraRedox.h b/src/sensors/PaleoTerraRedox.h index 2ca5e616d..43e3743b7 100644 --- a/src/sensors/PaleoTerraRedox.h +++ b/src/sensors/PaleoTerraRedox.h @@ -254,7 +254,7 @@ class PaleoTerraRedox : public Sensor { * This begins the Wire library (sets pin levels and modes for I2C) and * updates the #_sensorStatus. No sensor power is required. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; /** diff --git a/src/sensors/RainCounterI2C.h b/src/sensors/RainCounterI2C.h index 759e6ec1d..1114a12d8 100644 --- a/src/sensors/RainCounterI2C.h +++ b/src/sensors/RainCounterI2C.h @@ -273,7 +273,7 @@ class RainCounterI2C : public Sensor { * This begins the Wire library (sets pin levels and modes for I2C) and * updates the #_sensorStatus. No sensor power is required. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; /** diff --git a/src/sensors/SDI12Sensors.h b/src/sensors/SDI12Sensors.h index 46fea846c..fbf17d09b 100644 --- a/src/sensors/SDI12Sensors.h +++ b/src/sensors/SDI12Sensors.h @@ -211,7 +211,7 @@ class SDI12Sensors : public Sensor { * sensor and calls the getSensorInfo() function. Sensor power **is** * required. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; @@ -226,7 +226,7 @@ class SDI12Sensors : public Sensor { * @note This function does NOT include any waiting for the sensor to be * warmed up or stable! * - * @return **bool** True if the start measurement function completed + * @return True if the start measurement function completed * successfully. */ bool startSingleMeasurement(void) override; @@ -241,7 +241,7 @@ class SDI12Sensors : public Sensor { * @brief Send the SDI-12 'acknowledge active' command [address][!] to a * sensor and confirm that the correct sensor responded. * - * @return **bool** True if the correct SDI-12 sensor replied to the + * @return True if the correct SDI-12 sensor replied to the * command. */ bool requestSensorAcknowledgement(void); @@ -249,7 +249,7 @@ class SDI12Sensors : public Sensor { * @brief Send the SDI-12 'info' command [address][I][!] to a sensor and * parse the result into the vendor, model, version, and serial number. * - * @return **bool** True if all expected information fields returned by the + * @return True if all expected information fields returned by the * sensor. */ bool getSensorInfo(void); @@ -264,14 +264,14 @@ class SDI12Sensors : public Sensor { * @param isConcurrent Whether to start a concurrent or standard * measurement. Defaults to 'true' for a concurrent measurement. * - * @return **int8_t** The length of time the measurement is expected to + * @return The length of time the measurement is expected to * take. */ int8_t startSDI12Measurement(bool isConcurrent = true); /** * @brief Gets the results of either a standard or a concurrent measurement * - * @return **bool** True if the full number of expected results was + * @return True if the full number of expected results was * returned. */ virtual bool getResults(void); diff --git a/src/sensors/SensirionSHT4x.h b/src/sensors/SensirionSHT4x.h index 76548da38..016a1acf9 100644 --- a/src/sensors/SensirionSHT4x.h +++ b/src/sensors/SensirionSHT4x.h @@ -251,7 +251,7 @@ class SensirionSHT4x : public Sensor { /** * @brief Report the I2C address of the SHT4x - which is always 0x44. * - * @return **String** Text describing how the sensor is attached to the mcu. + * @return Text describing how the sensor is attached to the mcu. */ String getSensorLocation(void) override; @@ -263,7 +263,7 @@ class SensirionSHT4x : public Sensor { * and modes for I2C), and updates the #_sensorStatus. No sensor power is * required. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; diff --git a/src/sensors/TIINA219.h b/src/sensors/TIINA219.h index f53609dc9..60141e3ef 100644 --- a/src/sensors/TIINA219.h +++ b/src/sensors/TIINA219.h @@ -270,7 +270,7 @@ class TIINA219 : public Sensor { * * @note This does NOT include any wait for sensor readiness. * - * @return **bool** True if the wake function completed successfully. + * @return True if the wake function completed successfully. */ bool wake(void) override; /** @@ -281,7 +281,7 @@ class TIINA219 : public Sensor { * and modes for I2C). This also sets the calibration range of the INA219, * and updates the #_sensorStatus. The INA219 must be powered for setup. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; /** diff --git a/src/sensors/TallyCounterI2C.h b/src/sensors/TallyCounterI2C.h index 2a4f861c9..29e68001e 100644 --- a/src/sensors/TallyCounterI2C.h +++ b/src/sensors/TallyCounterI2C.h @@ -206,7 +206,7 @@ class TallyCounterI2C : public Sensor { * #_sensorStatus. It also engages sleep mode on the Tally counter and * clears the counter memory. The Tally must be powered for setup. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; /** diff --git a/src/sensors/YosemitechParent.h b/src/sensors/YosemitechParent.h index b63e67cd9..13b4efe30 100644 --- a/src/sensors/YosemitechParent.h +++ b/src/sensors/YosemitechParent.h @@ -218,7 +218,7 @@ class YosemitechParent : public Sensor { * updates the #_sensorStatus. No sensor power is required. This will * always return true. * - * @return **bool** True if the setup was successful. + * @return True if the setup was successful. */ bool setup(void) override; /** @@ -230,7 +230,7 @@ class YosemitechParent : public Sensor { * * @note This does NOT include any wait for sensor readiness. * - * @return **bool** True if the wake function completed successfully. + * @return True if the wake function completed successfully. */ bool wake(void) override; /** @@ -239,7 +239,7 @@ class YosemitechParent : public Sensor { * This also un-sets the #_millisSensorActivated timestamp (sets it to 0). * This does NOT power down the sensor! * - * @return **bool** True if the sleep function completed successfully. + * @return True if the sleep function completed successfully. */ bool sleep(void) override; From 011dc737fd0af31da5c8cc56b5cd3937baf12ca5 Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Thu, 19 Sep 2024 16:36:22 -0400 Subject: [PATCH 137/138] Fix some docs Signed-off-by: Sara Damiano --- src/modems/EspressifESP8266.h | 4 ++-- src/publishers/UbidotsPublisher.h | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/modems/EspressifESP8266.h b/src/modems/EspressifESP8266.h index be33c4fb5..c3494dfb0 100644 --- a/src/modems/EspressifESP8266.h +++ b/src/modems/EspressifESP8266.h @@ -277,8 +277,8 @@ class EspressifESP8266 : public loggerModem { * up string. Because the boot up string is at a different baud rate (74880 * baud), it usually comes out as junk. * - * @return *true* Text (assumed to be the start message) was received - * @return *false* No boot text was receivedd + * @return True if text (assumed to be the start message) was received; + * false if text was received after boot. */ bool ESPwaitForBoot(void); const char* _ssid; ///< Internal reference to the WiFi SSID diff --git a/src/publishers/UbidotsPublisher.h b/src/publishers/UbidotsPublisher.h index fd680a813..7e1437ec5 100644 --- a/src/publishers/UbidotsPublisher.h +++ b/src/publishers/UbidotsPublisher.h @@ -106,6 +106,12 @@ class UbidotsPublisher : public dataPublisher { virtual ~UbidotsPublisher(); // Returns the data destination + /** + * @brief Get the destination for published data - generally the host name + * of the data receiver. + * + * @return The URL or HOST to receive published data + */ String getEndpoint(void) override { return String(ubidotsHost); } From d2bf503d1c3b0ace9a642eafc733bfa3cba0c4eb Mon Sep 17 00:00:00 2001 From: Sara Damiano Date: Tue, 24 Sep 2024 17:46:13 -0400 Subject: [PATCH 138/138] Update doxyfile Signed-off-by: Sara Damiano --- docs/Doxyfile | 6 +++--- docs/mcss-conf.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/Doxyfile b/docs/Doxyfile index 9a269c934..bb2eb2ad9 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -547,13 +547,13 @@ EXTRACT_ALL = NO # be included in the documentation. # The default value is: NO. -EXTRACT_PRIVATE = NO +EXTRACT_PRIVATE = YES # If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual # methods of a class will be included in the documentation. # The default value is: NO. -EXTRACT_PRIV_VIRTUAL = NO +EXTRACT_PRIV_VIRTUAL = YES # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. @@ -1348,7 +1348,7 @@ IGNORE_PREFIX = # If the GENERATE_HTML tag is set to YES, Doxygen will generate HTML output # The default value is: YES. -GENERATE_HTML = NO +GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of diff --git a/docs/mcss-conf.py b/docs/mcss-conf.py index 02f0cec67..0a9c1c85a 100644 --- a/docs/mcss-conf.py +++ b/docs/mcss-conf.py @@ -90,7 +90,7 @@ ), ], ), - ("Modules", "modules", []), + ("Topics", "topics", []), ( "Classes", "annotated",