From 67477b1f4ebe8d95f0601eb6f0b98a10eb51c5d8 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Sat, 31 Mar 2018 16:26:00 +0200 Subject: [PATCH 01/13] Add support for SGP30 sensor 5.12.0i * Add support for SGP30 gas and air quality sensor (#2307) --- .../.github/ISSUE_TEMPLATE.md | 46 ++++ .../.github/PULL_REQUEST_TEMPLATE.md | 26 ++ lib/Adafruit_SGP30-1.0.0.13/.gitignore | 4 + lib/Adafruit_SGP30-1.0.0.13/.travis.yml | 27 ++ .../Adafruit_SGP30.cpp | 243 ++++++++++++++++++ lib/Adafruit_SGP30-1.0.0.13/Adafruit_SGP30.h | 68 +++++ lib/Adafruit_SGP30-1.0.0.13/README.md | 18 ++ .../examples/sgp30test/sgp30test.ino | 45 ++++ .../library.properties | 9 + lib/Adafruit_SGP30-1.0.0.13/license.txt | 26 ++ sonoff/_releasenotes.ino | 5 +- sonoff/i18n.h | 7 +- sonoff/language/cs-CZ.h | 2 + sonoff/language/de-DE.h | 2 + sonoff/language/en-GB.h | 2 + sonoff/language/es-AR.h | 2 + sonoff/language/fr-FR.h | 2 + sonoff/language/hu-HU.h | 2 + sonoff/language/it-IT.h | 2 + sonoff/language/nl-NL.h | 2 + sonoff/language/pl-PL.h | 2 + sonoff/language/pt-PT.h | 2 + sonoff/language/ru-RU.h | 2 + sonoff/language/zh-CN.h | 2 + sonoff/language/zh-TW.h | 2 + sonoff/sonoff_post.h | 4 + sonoff/user_config.h | 1 + sonoff/xsns_21_sgp30.ino | 115 +++++++++ 28 files changed, 667 insertions(+), 3 deletions(-) create mode 100644 lib/Adafruit_SGP30-1.0.0.13/.github/ISSUE_TEMPLATE.md create mode 100644 lib/Adafruit_SGP30-1.0.0.13/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 lib/Adafruit_SGP30-1.0.0.13/.gitignore create mode 100644 lib/Adafruit_SGP30-1.0.0.13/.travis.yml create mode 100644 lib/Adafruit_SGP30-1.0.0.13/Adafruit_SGP30.cpp create mode 100644 lib/Adafruit_SGP30-1.0.0.13/Adafruit_SGP30.h create mode 100644 lib/Adafruit_SGP30-1.0.0.13/README.md create mode 100644 lib/Adafruit_SGP30-1.0.0.13/examples/sgp30test/sgp30test.ino create mode 100644 lib/Adafruit_SGP30-1.0.0.13/library.properties create mode 100644 lib/Adafruit_SGP30-1.0.0.13/license.txt create mode 100644 sonoff/xsns_21_sgp30.ino diff --git a/lib/Adafruit_SGP30-1.0.0.13/.github/ISSUE_TEMPLATE.md b/lib/Adafruit_SGP30-1.0.0.13/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..f0e26146f --- /dev/null +++ b/lib/Adafruit_SGP30-1.0.0.13/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,46 @@ +Thank you for opening an issue on an Adafruit Arduino library repository. To +improve the speed of resolution please review the following guidelines and +common troubleshooting steps below before creating the issue: + +- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use + the forums at http://forums.adafruit.com to ask questions and troubleshoot why + something isn't working as expected. In many cases the problem is a common issue + that you will more quickly receive help from the forum community. GitHub issues + are meant for known defects in the code. If you don't know if there is a defect + in the code then start with troubleshooting on the forum first. + +- **If following a tutorial or guide be sure you didn't miss a step.** Carefully + check all of the steps and commands to run have been followed. Consult the + forum if you're unsure or have questions about steps in a guide/tutorial. + +- **For Arduino projects check these very common issues to ensure they don't apply**: + + - For uploading sketches or communicating with the board make sure you're using + a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes + very hard to tell the difference between a data and charge cable! Try using the + cable with other devices or swapping to another cable to confirm it is not + the problem. + + - **Be sure you are supplying adequate power to the board.** Check the specs of + your board and plug in an external power supply. In many cases just + plugging a board into your computer is not enough to power it and other + peripherals. + + - **Double check all soldering joints and connections.** Flakey connections + cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. + + - **Ensure you are using an official Arduino or Adafruit board.** We can't + guarantee a clone board will have the same functionality and work as expected + with this code and don't support them. + +If you're sure this issue is a defect in the code and checked the steps above +please fill in the following fields to provide enough troubleshooting information. +You may delete the guideline and text above to just leave the following details: + +- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** + +- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO + VERSION HERE** + +- List the steps to reproduce the problem below (if possible attach a sketch or + copy the sketch code in too): **LIST REPRO STEPS BELOW** diff --git a/lib/Adafruit_SGP30-1.0.0.13/.github/PULL_REQUEST_TEMPLATE.md b/lib/Adafruit_SGP30-1.0.0.13/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..7b641eb86 --- /dev/null +++ b/lib/Adafruit_SGP30-1.0.0.13/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,26 @@ +Thank you for creating a pull request to contribute to Adafruit's GitHub code! +Before you open the request please review the following guidelines and tips to +help it be more easily integrated: + +- **Describe the scope of your change--i.e. what the change does and what parts + of the code were modified.** This will help us understand any risks of integrating + the code. + +- **Describe any known limitations with your change.** For example if the change + doesn't apply to a supported platform of the library please mention it. + +- **Please run any tests or examples that can exercise your modified code.** We + strive to not break users of the code and running tests/examples helps with this + process. + +Thank you again for contributing! We will try to test and integrate the change +as soon as we can, but be aware we have many GitHub repositories to manage and +can't immediately respond to every request. There is no need to bump or check in +on a pull request (it will clutter the discussion of the request). + +Also don't be worried if the request is closed or not integrated--sometimes the +priorities of Adafruit's GitHub code (education, ease of use) might not match the +priorities of the pull request. Don't fret, the open source community thrives on +forks and GitHub makes it easy to keep your changes in a forked repo. + +After reviewing the guidelines above you can delete this text from the pull request. diff --git a/lib/Adafruit_SGP30-1.0.0.13/.gitignore b/lib/Adafruit_SGP30-1.0.0.13/.gitignore new file mode 100644 index 000000000..7f189125f --- /dev/null +++ b/lib/Adafruit_SGP30-1.0.0.13/.gitignore @@ -0,0 +1,4 @@ +*~ +Doxyfile* +doxygen_sqlite3.db +html \ No newline at end of file diff --git a/lib/Adafruit_SGP30-1.0.0.13/.travis.yml b/lib/Adafruit_SGP30-1.0.0.13/.travis.yml new file mode 100644 index 000000000..428f3434e --- /dev/null +++ b/lib/Adafruit_SGP30-1.0.0.13/.travis.yml @@ -0,0 +1,27 @@ +language: c +sudo: false + +# Blacklist +branches: + except: + - gh-pages + +env: + global: + - PRETTYNAME="Adafruit SGP30 Arduino Library" +# Optional, will default to "$TRAVIS_BUILD_DIR/Doxyfile" +# - DOXYFILE: $TRAVIS_BUILD_DIR/Doxyfile + +before_install: + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh) + +#install: +# - arduino --install-library "Adafruit ILI9341","Adafruit GFX Library" + +script: + - build_main_platforms + +# Generate and deploy documentation +after_success: + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/library_check.sh) + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh) \ No newline at end of file diff --git a/lib/Adafruit_SGP30-1.0.0.13/Adafruit_SGP30.cpp b/lib/Adafruit_SGP30-1.0.0.13/Adafruit_SGP30.cpp new file mode 100644 index 000000000..b2ccbe8da --- /dev/null +++ b/lib/Adafruit_SGP30-1.0.0.13/Adafruit_SGP30.cpp @@ -0,0 +1,243 @@ +/*! + * @file Adafruit_SGP30.cpp + * + * @mainpage Adafruit SGP30 gas sensor driver + * + * @section intro_sec Introduction + * + * This is the documentation for Adafruit's SGP30 driver for the + * Arduino platform. It is designed specifically to work with the + * Adafruit SGP30 breakout: http://www.adafruit.com/products/3709 + * + * These sensors use I2C to communicate, 2 pins (SCL+SDA) are required + * to interface with the breakout. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * + * @section author Author + * Written by Ladyada for Adafruit Industries. + * + * @section license License + * BSD license, all text here must be included in any redistribution. + * + */ + + +#if ARDUINO >= 100 + #include "Arduino.h" +#else + #include "WProgram.h" +#endif + +#include "Adafruit_SGP30.h" + +//#define I2C_DEBUG + +/**************************************************************************/ +/*! + @brief Instantiates a new SGP30 class +*/ +/**************************************************************************/ +Adafruit_SGP30::Adafruit_SGP30() { +} + +/**************************************************************************/ +/*! + @brief Setups the hardware and detects a valid SGP30. Initializes I2C + then reads the serialnumber and checks that we are talking to an SGP30 + @param theWire Optional pointer to I2C interface, otherwise use Wire + @returns True if SGP30 found on I2C, False if something went wrong! +*/ +/**************************************************************************/ +boolean Adafruit_SGP30::begin(TwoWire *theWire) { + _i2caddr = SGP30_I2CADDR_DEFAULT; + if (theWire == NULL) { + _i2c = &Wire; + } else { + _i2c = theWire; + } + + _i2c->begin(); + + + uint8_t command[2]; + command[0] = 0x36; + command[1] = 0x82; + if (! readWordFromCommand(command, 2, 10, serialnumber, 3)) + return false; + + uint16_t featureset; + command[0] = 0x20; + command[1] = 0x2F; + if (! readWordFromCommand(command, 2, 10, &featureset, 1)) + return false; + //Serial.print("Featureset 0x"); Serial.println(featureset, HEX); + if (featureset != SGP30_FEATURESET) + return false; + if (! IAQinit()) + return false; + + return true; +} + +/**************************************************************************/ +/*! + @brief Commands the sensor to begin the IAQ algorithm. Must be called after startup. + @returns True if command completed successfully, false if something went wrong! +*/ +/**************************************************************************/ +boolean Adafruit_SGP30::IAQinit(void) { + uint8_t command[2]; + command[0] = 0x20; + command[1] = 0x03; + return readWordFromCommand(command, 2, 10); +} + +/**************************************************************************/ +/*! + @brief Commands the sensor to take a single eCO2/VOC measurement. Places results in {@link TVOC} and {@link eCO2} + @returns True if command completed successfully, false if something went wrong! +*/ +/**************************************************************************/ +boolean Adafruit_SGP30::IAQmeasure(void) { + uint8_t command[2]; + command[0] = 0x20; + command[1] = 0x08; + uint16_t reply[2]; + if (! readWordFromCommand(command, 2, 12, reply, 2)) + return false; + TVOC = reply[1]; + eCO2 = reply[0]; + return true; +} + +/**************************************************************************/ +/*! + @brief Request baseline calibration values for both CO2 and TVOC IAQ calculations. Places results in parameter memory locaitons. + @param eco2_base A pointer to a uint16_t which we will save the calibration value to + @param tvoc_base A pointer to a uint16_t which we will save the calibration value to + @returns True if command completed successfully, false if something went wrong! +*/ +/**************************************************************************/ +boolean Adafruit_SGP30::getIAQBaseline(uint16_t *eco2_base, uint16_t *tvoc_base) { + uint8_t command[2]; + command[0] = 0x20; + command[1] = 0x15; + uint16_t reply[2]; + if (! readWordFromCommand(command, 2, 10, reply, 2)) + return false; + *eco2_base = reply[0]; + *tvoc_base = reply[1]; + return true; +} + +/**************************************************************************/ +/*! + @brief Assign baseline calibration values for both CO2 and TVOC IAQ calculations. + @param eco2_base A uint16_t which we will save the calibration value from + @param tvoc_base A uint16_t which we will save the calibration value from + @returns True if command completed successfully, false if something went wrong! +*/ +/**************************************************************************/ +boolean Adafruit_SGP30::setIAQBaseline(uint16_t eco2_base, uint16_t tvoc_base) { + uint8_t command[8]; + command[0] = 0x20; + command[1] = 0x1e; + command[2] = tvoc_base >> 8; + command[3] = tvoc_base & 0xFF; + command[4] = generateCRC(command+2, 2); + command[5] = eco2_base >> 8; + command[6] = eco2_base & 0xFF; + command[7] = generateCRC(command+5, 2); + + return readWordFromCommand(command, 8, 10); +} + +/**************************************************************************/ +/*! + @brief I2C low level interfacing +*/ +/**************************************************************************/ + + +boolean Adafruit_SGP30::readWordFromCommand(uint8_t command[], uint8_t commandLength, uint16_t delayms, uint16_t *readdata, uint8_t readlen) +{ + uint8_t data; + + _i2c->beginTransmission(_i2caddr); + +#ifdef I2C_DEBUG + Serial.print("\t\t-> "); +#endif + + for (uint8_t i=0; iwrite(command[i]); +#ifdef I2C_DEBUG + Serial.print("0x"); Serial.print(command[i], HEX); Serial.print(", "); +#endif + } +#ifdef I2C_DEBUG + Serial.println(); +#endif + _i2c->endTransmission(); + + delay(delayms); + + if (readlen == 0) + return true; + + uint8_t replylen = readlen * (SGP30_WORD_LEN +1); + if (_i2c->requestFrom(_i2caddr, replylen) != replylen) + return false; + uint8_t replybuffer[replylen]; +#ifdef I2C_DEBUG + Serial.print("\t\t<- "); +#endif + for (uint8_t i=0; iread(); +#ifdef I2C_DEBUG + Serial.print("0x"); Serial.print(replybuffer[i], HEX); Serial.print(", "); +#endif + } + +#ifdef I2C_DEBUG + Serial.println(); +#endif + + for (uint8_t i=0; i + +// the i2c address +#define SGP30_I2CADDR_DEFAULT 0x58 ///< SGP30 has only one I2C address + +// commands and constants +#define SGP30_FEATURESET 0x0020 ///< The required set for this library +#define SGP30_CRC8_POLYNOMIAL 0x31 ///< Seed for SGP30's CRC polynomial +#define SGP30_CRC8_INIT 0xFF ///< Init value for CRC +#define SGP30_WORD_LEN 2 ///< 2 bytes per word + +/**************************************************************************/ +/*! Class that stores state and functions for interacting with SGP30 Gas Sensor */ +/**************************************************************************/ +class Adafruit_SGP30 { + public: + Adafruit_SGP30(); + boolean begin(TwoWire *theWire = NULL); + boolean IAQinit(void); + boolean IAQmeasure(void); + + boolean getIAQBaseline(uint16_t *eco2_base, uint16_t *tvoc_base); + boolean setIAQBaseline(uint16_t eco2_base, uint16_t tvoc_base); + + /** + * The last measurement of the IAQ-calculated Total Volatile Organic Compounds in ppb. This value is set when you call {@link IAQmeasure()} + */ + uint16_t TVOC; + + /** + * The last measurement of the IAQ-calculated equivalent CO2 in ppm. This value is set when you call {@link IAQmeasure()} + */ + uint16_t eCO2; + + /** + * The 48-bit serial number, this value is set when you call {@link begin()} + */ + uint16_t serialnumber[3]; + private: + TwoWire *_i2c; + uint8_t _i2caddr; + + void write(uint8_t address, uint8_t *data, uint8_t n); + void read(uint8_t address, uint8_t *data, uint8_t n); + boolean readWordFromCommand(uint8_t command[], uint8_t commandLength, uint16_t delay, uint16_t *readdata = NULL, uint8_t readlen = 0); + uint8_t generateCRC(uint8_t data[], uint8_t datalen); +}; diff --git a/lib/Adafruit_SGP30-1.0.0.13/README.md b/lib/Adafruit_SGP30-1.0.0.13/README.md new file mode 100644 index 000000000..44056b5c8 --- /dev/null +++ b/lib/Adafruit_SGP30-1.0.0.13/README.md @@ -0,0 +1,18 @@ +Adafruit_SGP30 +================ + +This is the Adafruit SGP30 Gas / Air Quality I2C sensor library + +Tested and works great with the Aadafruit SGP30 Breakout Board + * http://www.adafruit.com/products/3709 + +This chip uses I2C to communicate, 2 pins are required to interface + +Adafruit invests time and resources providing this open source code, +please support Adafruit and open-source hardware by purchasing +products from Adafruit! + +Written by Limor Fried for Adafruit Industries. +BSD license, check license.txt for more information +All text above must be included in any redistribution + diff --git a/lib/Adafruit_SGP30-1.0.0.13/examples/sgp30test/sgp30test.ino b/lib/Adafruit_SGP30-1.0.0.13/examples/sgp30test/sgp30test.ino new file mode 100644 index 000000000..6b9b3ea05 --- /dev/null +++ b/lib/Adafruit_SGP30-1.0.0.13/examples/sgp30test/sgp30test.ino @@ -0,0 +1,45 @@ +#include +#include "Adafruit_SGP30.h" + +Adafruit_SGP30 sgp; + +void setup() { + Serial.begin(9600); + Serial.println("SGP30 test"); + + if (! sgp.begin()){ + Serial.println("Sensor not found :("); + while (1); + } + Serial.print("Found SGP30 serial #"); + Serial.print(sgp.serialnumber[0], HEX); + Serial.print(sgp.serialnumber[1], HEX); + Serial.println(sgp.serialnumber[2], HEX); + + // If you have a baseline measurement from before you can assign it to start, to 'self-calibrate' + //sgp.setIAQBaseline(0x8E68, 0x8F41); // Will vary for each sensor! +} + +int counter = 0; +void loop() { + if (! sgp.IAQmeasure()) { + Serial.println("Measurement failed"); + return; + } + Serial.print("TVOC "); Serial.print(sgp.TVOC); Serial.print(" ppb\t"); + Serial.print("eCO2 "); Serial.print(sgp.eCO2); Serial.println(" ppm"); + delay(1000); + + counter++; + if (counter == 30) { + counter = 0; + + uint16_t TVOC_base, eCO2_base; + if (! sgp.getIAQBaseline(&eCO2_base, &TVOC_base)) { + Serial.println("Failed to get baseline readings"); + return; + } + Serial.print("****Baseline values: eCO2: 0x"); Serial.print(eCO2_base, HEX); + Serial.print(" & TVOC: 0x"); Serial.println(TVOC_base, HEX); + } +} \ No newline at end of file diff --git a/lib/Adafruit_SGP30-1.0.0.13/library.properties b/lib/Adafruit_SGP30-1.0.0.13/library.properties new file mode 100644 index 000000000..3520b4d38 --- /dev/null +++ b/lib/Adafruit_SGP30-1.0.0.13/library.properties @@ -0,0 +1,9 @@ +name=Adafruit SGP30 Sensor +version=1.0.2 +author=Adafruit +maintainer=Adafruit +sentence=This is an Arduino library for the Adafruit SGP30 Gas / Air Quality Sensor +paragraph=This is an Arduino library for the Adafruit SGP30 Gas / Air Quality Sensor +category=Sensors +url=https://github.com/adafruit/Adafruit_SGP30 +architectures=* diff --git a/lib/Adafruit_SGP30-1.0.0.13/license.txt b/lib/Adafruit_SGP30-1.0.0.13/license.txt new file mode 100644 index 000000000..f6a0f22b8 --- /dev/null +++ b/lib/Adafruit_SGP30-1.0.0.13/license.txt @@ -0,0 +1,26 @@ +Software License Agreement (BSD License) + +Copyright (c) 2012, Adafruit Industries +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holders nor the +names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index e65516123..35ae88f27 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -2,11 +2,12 @@ * Add 16 timers using commands Timer and Timers (#1091) * Add commands Timer 0 to clear timer and Timer 1..16 to copy timer * Add optional Timer configuration webpage to be enabled in user_config.h with define USE_TIMERS_WEB - * Change MQTT response topic for Energy changes from ENERGY to SENSOR (#2229, #2251) * Add Home Assistant MQTT Discovery for Buttons and change SetOption19 response (#2277) + * Add support for SGP30 gas and air quality sensor (#2307) * Change webpage parameter communication - * Change default Reset configuration time from 4 seconds to 40 seconds on Button hold (#2268) * Change Timer parameter Device to more obvious Output + * Change MQTT response topic for Energy changes from ENERGY to SENSOR (#2229, #2251) + * Change default Reset configuration time from 4 seconds to 40 seconds on Button hold (#2268) * * 5.12.0h * Add optional Arduino OTA support to be enabled in user_config.h (#1998) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index dcc7024a0..12db1d541 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -111,6 +111,7 @@ #define D_JSON_TIME "Time" #define D_JSON_TODAY "Today" #define D_JSON_TOTAL "Total" +#define D_JSON_TVOC "TVOC" #define D_JSON_TYPE "Type" #define D_JSON_UPTIME "Uptime" #define D_JSON_UTC_TIME "UTC" @@ -381,6 +382,8 @@ enum UnitNames { UNIT_MILLIAMPERE, UNIT_MILLISECOND, UNIT_MINUTE, + UNIT_PPB, + UNIT_PPD, UNIT_PPM, UNIT_PERCENTAGE, UNIT_PRESSURE, @@ -399,6 +402,8 @@ const char kUnitNames[] PROGMEM = D_UNIT_MILLIAMPERE "|" D_UNIT_MILLISECOND "|" D_UNIT_MINUTE "|" + D_UNIT_PARTS_PER_BILLION "|" + D_UNIT_PARTS_PER_DECILITER "|" D_UNIT_PARTS_PER_MILLION "|" "%|" D_UNIT_PRESSURE "|" @@ -475,7 +480,7 @@ const char HTTP_SNS_PRESSURE[] PROGMEM = "%s{s}%s " D_PRESSURE "{m}%s " D_UNIT_P const char HTTP_SNS_SEAPRESSURE[] PROGMEM = "%s{s}%s " D_PRESSUREATSEALEVEL "{m}%s " D_UNIT_PRESSURE "{e}"; // {s} = , {m} = , {e} = const char HTTP_SNS_ANALOG[] PROGMEM = "%s{s}%s " D_ANALOG_INPUT "%d{m}%d{e}"; // {s} = , {m} = , {e} = -#if defined(USE_MHZ19) || defined(USE_SENSEAIR) +#if defined(USE_MHZ19) || defined(USE_SENSEAIR) || defined(USE_SGP30) const char HTTP_SNS_CO2[] PROGMEM = "%s{s}%s " D_CO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"; // {s} = , {m} = , {e} = #endif // USE_WEBSERVER diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index 8e953810e..9f2740ecb 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -142,6 +142,7 @@ #define D_TOPIC "Topic" #define D_TRANSMIT "Odešli" #define D_TRUE "Pravda" +#define D_TVOC "TVOC" #define D_UPGRADE "aktualizace" #define D_UPLOAD "Nahrání..." #define D_UPTIME "Uptime" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "mA" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "hPa" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 7e50360d0..45040412e 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -142,6 +142,7 @@ #define D_TOPIC "topic" #define D_TRANSMIT "Übertragen" #define D_TRUE "wahr" +#define D_TVOC "TVOC" #define D_UPGRADE "update" #define D_UPLOAD "Upload" #define D_UPTIME "Laufzeit" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "mA" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "min" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "hPa" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index c0ead99f8..dadd68f85 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -142,6 +142,7 @@ #define D_TOPIC "Topic" #define D_TRANSMIT "Transmit" #define D_TRUE "True" +#define D_TVOC "TVOC" #define D_UPGRADE "upgrade" #define D_UPLOAD "Upload" #define D_UPTIME "Uptime" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "mA" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "hPa" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index 891a313ab..ae9acf887 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -142,6 +142,7 @@ #define D_TOPIC "Topic" #define D_TRANSMIT "Transmitir" #define D_TRUE "Verdadero" +#define D_TVOC "TVOC" #define D_UPGRADE "Actualización" #define D_UPLOAD "Carga" #define D_UPTIME "Tiempo Encendido" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "mA" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "hPa" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index e021604de..d5a62db80 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -142,6 +142,7 @@ #define D_TOPIC "Topic" #define D_TRANSMIT "Transmettre" #define D_TRUE "Vrai" +#define D_TVOC "TVOC" #define D_UPGRADE "upgrade" #define D_UPLOAD "Upload" #define D_UPTIME "Uptime" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "mA" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "hPa" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index 6288b743a..f4dc7a0c9 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -142,6 +142,7 @@ #define D_TOPIC "Téma" #define D_TRANSMIT "Továbbít" #define D_TRUE "Igaz" +#define D_TVOC "TVOC" #define D_UPGRADE "frissítés" #define D_UPLOAD "Feltöltés" #define D_UPTIME "Üzemidő" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "mA" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "p" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "hPa" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index 64383eec4..8a3a80702 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -142,6 +142,7 @@ #define D_TOPIC "Topic" #define D_TRANSMIT "Trasmesso" #define D_TRUE "True" +#define D_TVOC "TVOC" #define D_UPGRADE "aggiornamento" #define D_UPLOAD "Invio" #define D_UPTIME "Uptime" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "mA" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "hPa" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index 2d1fbaf31..507213f07 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -142,6 +142,7 @@ #define D_TOPIC "Topic" // Onderwerp #define D_TRANSMIT "Verzend" #define D_TRUE "Waar" +#define D_TVOC "TVOC" #define D_UPGRADE "opwaarderen" #define D_UPLOAD "Verzenden" #define D_UPTIME "Bedrijfstijd" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "mA" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "hPa" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 9cd364d43..856e682bf 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -142,6 +142,7 @@ #define D_TOPIC "Temat" #define D_TRANSMIT "Wyślij" #define D_TRUE "Prawda" +#define D_TVOC "TVOC" #define D_UPGRADE "aktualizacji" #define D_UPLOAD "Wgraj" #define D_UPTIME "Uptime" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "mA" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "hPa" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index 2f4d40a1d..482e40474 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -142,6 +142,7 @@ #define D_TOPIC "Tópico" #define D_TRANSMIT "Transmitir" #define D_TRUE "Verdadeiro" +#define D_TVOC "TVOC" #define D_UPGRADE "Atualizar" #define D_UPLOAD "Enviar" #define D_UPTIME "Tempo de Atividade" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "mA" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "hPa" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index aad061b0c..ee84a50b0 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -142,6 +142,7 @@ #define D_TOPIC "Топик" #define D_TRANSMIT "Передать" #define D_TRUE "Истина" +#define D_TVOC "TVOC" #define D_UPGRADE "обновление" #define D_UPLOAD "Загрузить" #define D_UPTIME "Uptime" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "мА" #define D_UNIT_MILLISECOND "мс" #define D_UNIT_MINUTE "мин" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "гПа" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index 4fadd8592..a105a9c3a 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -142,6 +142,7 @@ #define D_TOPIC "主题" #define D_TRANSMIT "发送" #define D_TRUE "True" +#define D_TVOC "TVOC" #define D_UPGRADE "升级" #define D_UPLOAD "上传" #define D_UPTIME "运行时间" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "毫安" #define D_UNIT_MILLISECOND "毫秒" #define D_UNIT_MINUTE "分" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "每分升" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "百帕" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index f6b8e8ecd..118e0d719 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -142,6 +142,7 @@ #define D_TOPIC "主題" #define D_TRANSMIT "發送" #define D_TRUE "True" +#define D_TVOC "TVOC" #define D_UPGRADE "升級" #define D_UPLOAD "上傳" #define D_UPTIME "運行時間" @@ -437,6 +438,7 @@ #define D_UNIT_MILLIAMPERE "毫安" #define D_UNIT_MILLISECOND "毫秒" #define D_UNIT_MINUTE "分" +#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "每分升" #define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PRESSURE "百帕" diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h index 09b4836ba..67678c6e2 100644 --- a/sonoff/sonoff_post.h +++ b/sonoff/sonoff_post.h @@ -45,6 +45,7 @@ void WifiWpsStatusCallback(wps_cb_status status); #define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor (+1k5 code) #define USE_BMP // Add I2C code for BMP085/BMP180/BMP280/BME280 sensor (+4k code) #define USE_BME680 // Add additional support for BME680 sensor using Adafruit Sensor and BME680 libraries (+6k code) +#define USE_SGP30 // Add I2C code for SGP30 sensor (+4k code) #define USE_BH1750 // Add I2C code for BH1750 sensor (+0k5 code) #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0k5 code) #define USE_TSL2561 // Add I2C code for TSL2561 sensor using library Adafruit TSL2561 Arduino (+1k2 code) @@ -101,6 +102,9 @@ void WifiWpsStatusCallback(wps_cb_status status); #ifdef USE_EMULATION #undef USE_EMULATION // Disable Wemo or Hue emulation #endif +#ifdef USE_TIMERS +#undef USE_TIMERS // Disable support for up to 16 timers +#endif #ifdef USE_PZEM004T #undef USE_PZEM004T // Disable PZEM004T energy sensor #endif diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 68cafc6be..5b274624a 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -206,6 +206,7 @@ #define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor (+1k5 code) #define USE_BMP // Add I2C code for BMP085/BMP180/BMP280/BME280 sensor (+4k code) // #define USE_BME680 // Add additional support for BME680 sensor using Adafruit Sensor and BME680 libraries (+6k code) + #define USE_SGP30 // Add I2C code for SGP30 sensor (+1k1 code) #define USE_BH1750 // Add I2C code for BH1750 sensor (+0k5 code) // #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0k5 code) // #define USE_TSL2561 // Add I2C code for TSL2561 sensor using library Joba_Tsl2561 (+2k3 code) diff --git a/sonoff/xsns_21_sgp30.ino b/sonoff/xsns_21_sgp30.ino new file mode 100644 index 000000000..205c34437 --- /dev/null +++ b/sonoff/xsns_21_sgp30.ino @@ -0,0 +1,115 @@ +/* + xsns_21_sgp30.ino - SGP30 gas and air quality sensor support for Sonoff-Tasmota + + Copyright (C) 2018 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_I2C +#ifdef USE_SGP30 +/*********************************************************************************************\ + * SGP30 - Gas (TVOC - Total Volatile Organic Compounds) and Air Quality (CO2) + * + * Source: Gerhard Mutz and Adafruit Industries + * + * I2C Address: 0x58 +\*********************************************************************************************/ + +#include "Adafruit_SGP30.h" +Adafruit_SGP30 sgp; + +uint8_t sgp30_type = 0; +uint8_t sgp30_ready = 0; +uint8_t sgp30_counter = 0; + +/********************************************************************************************/ + +void Sgp30Update() // Perform every second to ensure proper operation of the baseline compensation algorithm +{ + sgp30_ready = 0; + if (!sgp30_type) { + if (sgp.begin()) { + sgp30_type = 1; +// snprintf_P(log_data, sizeof(log_data), PSTR("SGP: Serialnumber 0x%04X-0x%04X-0x%04X"), sgp.serialnumber[0], sgp.serialnumber[1], sgp.serialnumber[2]); +// AddLog(LOG_LEVEL_DEBUG); + snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "SGP30", 0x58); + AddLog(LOG_LEVEL_DEBUG); + } + } else { + if (!sgp.IAQmeasure()) return; // Measurement failed + sgp30_counter++; + if (30 == sgp30_counter) { + sgp30_counter = 0; + + uint16_t TVOC_base; + uint16_t eCO2_base; + + if (!sgp.getIAQBaseline(&eCO2_base, &TVOC_base)) return; // Failed to get baseline readings +// snprintf_P(log_data, sizeof(log_data), PSTR("SGP: Baseline values eCO2 0x%04X, TVOC 0x%04X"), eCO2_base, TVOC_base); +// AddLog(LOG_LEVEL_DEBUG); + } + sgp30_ready = 1; + } +} + +const char HTTP_SNS_TVOC[] PROGMEM = "%s{s}SGP30 " D_TVOC "{m}%d " D_UNIT_PARTS_PER_BILLION "{e}"; + +void Sgp30Show(boolean json) +{ + if (sgp30_ready) { + if (json) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SGP30\":{\"" D_JSON_CO2 "\":%d,\"" D_JSON_TVOC "\":%d}"), mqtt_data, sgp.eCO2, sgp.TVOC); +#ifdef USE_DOMOTICZ + DomoticzSensor(DZ_AIRQUALITY, sgp.eCO2); +#endif // USE_DOMOTICZ + } else { +#ifdef USE_WEBSERVER + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_CO2, mqtt_data, "SGP30", sgp.eCO2); + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TVOC, mqtt_data, sgp.TVOC); +#endif + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +#define XSNS_21 + +boolean Xsns21(byte function) +{ + boolean result = false; + + if (i2c_flg) { + switch (function) { + case FUNC_EVERY_SECOND: + Sgp30Update(); + break; + case FUNC_JSON_APPEND: + Sgp30Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_APPEND: + Sgp30Show(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_SGP30 +#endif // USE_I2C \ No newline at end of file From 823c9a040484935bab6b70318ff7e03105edce82 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Sat, 31 Mar 2018 17:29:00 +0200 Subject: [PATCH 02/13] Add more validation to timer handling Add more validation to timer handling --- sonoff/i18n.h | 1 + sonoff/sonoff_post.h | 2 +- sonoff/webserver.ino | 22 +++++--- sonoff/xdrv_09_timers.ino | 107 ++++++++++++++++++++------------------ 4 files changed, 72 insertions(+), 60 deletions(-) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index 12db1d541..b026d0af5 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -358,6 +358,7 @@ #define D_JSON_TIMER_REPEAT "Repeat" #define D_JSON_TIMER_OUTPUT "Output" #define D_JSON_TIMER_POWER "Power" + #define D_JSON_TIMER_NO_DEVICE "No GPIO as output configured" #define D_CMND_TIMERS "Timers" /********************************************************************************************/ diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h index 67678c6e2..f1f980edf 100644 --- a/sonoff/sonoff_post.h +++ b/sonoff/sonoff_post.h @@ -45,7 +45,7 @@ void WifiWpsStatusCallback(wps_cb_status status); #define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor (+1k5 code) #define USE_BMP // Add I2C code for BMP085/BMP180/BMP280/BME280 sensor (+4k code) #define USE_BME680 // Add additional support for BME680 sensor using Adafruit Sensor and BME680 libraries (+6k code) -#define USE_SGP30 // Add I2C code for SGP30 sensor (+4k code) +#define USE_SGP30 // Add I2C code for SGP30 sensor (+1k1 code) #define USE_BH1750 // Add I2C code for BH1750 sensor (+0k5 code) #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0k5 code) #define USE_TSL2561 // Add I2C code for TSL2561 sensor using library Adafruit TSL2561 Arduino (+1k2 code) diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino index 45bde262f..b697e2bab 100644 --- a/sonoff/webserver.ino +++ b/sonoff/webserver.ino @@ -181,15 +181,17 @@ const char HTTP_BTN_MENU1[] PROGMEM = "
"; const char HTTP_BTN_RSTRT[] PROGMEM = "
"; -const char HTTP_BTN_MENU2[] PROGMEM = - "
" +const char HTTP_BTN_MENU_MODULE[] PROGMEM = + "
"; #ifdef USE_TIMERS #ifdef USE_TIMERS_WEB - "
" +const char HTTP_BTN_MENU_TIMER[] PROGMEM = + "
"; #endif // USE_TIMERS_WEB #endif // USE_TIMERS +const char HTTP_BTN_MENU_WIFI[] PROGMEM = "
"; -const char HTTP_BTN_MENU3[] PROGMEM = +const char HTTP_BTN_MENU_MQTT[] PROGMEM = "
" #ifdef USE_DOMOTICZ "
" @@ -629,10 +631,14 @@ void HandleConfiguration() String page = FPSTR(HTTP_HEAD); page.replace(F("{v}"), FPSTR(S_CONFIGURATION)); page += FPSTR(HTTP_HEAD_STYLE); - page += FPSTR(HTTP_BTN_MENU2); - if (Settings.flag.mqtt_enabled) { - page += FPSTR(HTTP_BTN_MENU3); - } + page += FPSTR(HTTP_BTN_MENU_MODULE); +#ifdef USE_TIMERS +#ifdef USE_TIMERS_WEB + if (devices_present) page += FPSTR(HTTP_BTN_MENU_TIMER); +#endif // USE_TIMERS_WEB +#endif // USE_TIMERS + page += FPSTR(HTTP_BTN_MENU_WIFI); + if (Settings.flag.mqtt_enabled) page += FPSTR(HTTP_BTN_MENU_MQTT); page += FPSTR(HTTP_BTN_MENU4); page += FPSTR(HTTP_BTN_MAIN); ShowPage(page); diff --git a/sonoff/xdrv_09_timers.ino b/sonoff/xdrv_09_timers.ino index f1ddeb68c..b82eb7e2c 100644 --- a/sonoff/xdrv_09_timers.ino +++ b/sonoff/xdrv_09_timers.ino @@ -97,65 +97,70 @@ boolean TimerCommand() Settings.timer[index -1].data = Settings.timer[XdrvMailbox.payload -1].data; // Copy timer } } else { - StaticJsonBuffer<128> jsonBuffer; - JsonObject& root = jsonBuffer.parseObject(dataBufUc); - if (!root.success()) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TIMER "%d\":\"" D_JSON_INVALID_JSON "\"}"), index); // JSON decode failed - error = 1; - } - else { - char parm_uc[10]; - index--; - if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_ARM))].success()) { - Settings.timer[index].arm = (root[parm_uc] != 0); + if (devices_present) { + StaticJsonBuffer<128> jsonBuffer; + JsonObject& root = jsonBuffer.parseObject(dataBufUc); + if (!root.success()) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TIMER "%d\":\"" D_JSON_INVALID_JSON "\"}"), index); // JSON decode failed + error = 1; } - if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_TIME))].success()) { - uint16_t itime = 0; - uint8_t value = 0; - char time_str[10]; + else { + char parm_uc[10]; + index--; + if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_ARM))].success()) { + Settings.timer[index].arm = (root[parm_uc] != 0); + } + if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_TIME))].success()) { + uint16_t itime = 0; + uint8_t value = 0; + char time_str[10]; - snprintf(time_str, sizeof(time_str), root[parm_uc]); - const char *substr = strtok(time_str, ":"); - if (substr != NULL) { - value = atoi(substr); - if (value > 23) value = 23; - itime = value * 60; - substr = strtok(NULL, ":"); + snprintf(time_str, sizeof(time_str), root[parm_uc]); + const char *substr = strtok(time_str, ":"); if (substr != NULL) { value = atoi(substr); - if (value > 59) value = 59; - itime += value; + if (value > 23) value = 23; + itime = value * 60; + substr = strtok(NULL, ":"); + if (substr != NULL) { + value = atoi(substr); + if (value > 59) value = 59; + itime += value; + } + } + Settings.timer[index].time = itime; + } + if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_DAYS))].success()) { + // SMTWTFS = 1234567 = 0011001 = 00TW00S = --TW--S + Settings.timer[index].days = 0; + const char *tday = root[parm_uc]; + char ch = '.'; + + uint8_t i = 0; + while ((ch != '\0') && (i < 7)) { + ch = *tday++; + if (ch == '-') ch = '0'; + uint8_t mask = 1 << i++; + Settings.timer[index].days |= (ch == '0') ? 0 : mask; } } - Settings.timer[index].time = itime; - } - if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_DAYS))].success()) { - // SMTWTFS = 1234567 = 0011001 = 00TW00S = --TW--S - Settings.timer[index].days = 0; - const char *tday = root[parm_uc]; - char ch = '.'; - - uint8_t i = 0; - while ((ch != '\0') && (i < 7)) { - ch = *tday++; - if (ch == '-') ch = '0'; - uint8_t mask = 1 << i++; - Settings.timer[index].days |= (ch == '0') ? 0 : mask; + if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_REPEAT))].success()) { + Settings.timer[index].repeat = (root[parm_uc] != 0); } - } - if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_REPEAT))].success()) { - Settings.timer[index].repeat = (root[parm_uc] != 0); - } - if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_OUTPUT))].success()) { - uint8_t device = ((uint8_t)root[parm_uc] -1) & 0x0F; - Settings.timer[index].device = (device < devices_present) ? device : devices_present -1; - } - if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_POWER))].success()) { - Settings.timer[index].power = (uint8_t)root[parm_uc] & 0x03; - } - if (Settings.timer[index].arm) bitClear(fired, index); + if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_OUTPUT))].success()) { + uint8_t device = ((uint8_t)root[parm_uc] -1) & 0x0F; + Settings.timer[index].device = (device < devices_present) ? device : devices_present -1; + } + if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_POWER))].success()) { + Settings.timer[index].power = (uint8_t)root[parm_uc] & 0x03; + } + if (Settings.timer[index].arm) bitClear(fired, index); - index++; + index++; + } + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TIMER "%d\":\"" D_JSON_TIMER_NO_DEVICE "\"}"), index); // No outputs defined so nothing to control + error = 1; } } } From 96212834cf3bbc31f8baf98fe7fb21a128e489ee Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Sat, 31 Mar 2018 18:59:37 +0200 Subject: [PATCH 03/13] Change Backlog max commands to 30 5.12.0i * Change max number of commands in Backlog from 15 to 30 --- sonoff/_releasenotes.ino | 1 + sonoff/sonoff.h | 2 +- sonoff/sonoff.ino | 18 +++++------------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 35ae88f27..f87587c10 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -6,6 +6,7 @@ * Add support for SGP30 gas and air quality sensor (#2307) * Change webpage parameter communication * Change Timer parameter Device to more obvious Output + * Change max number of commands in Backlog from 15 to 30 * Change MQTT response topic for Energy changes from ENERGY to SENSOR (#2229, #2251) * Change default Reset configuration time from 4 seconds to 40 seconds on Button hold (#2268) * diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 61ef81adb..0869c6929 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -97,7 +97,7 @@ typedef unsigned long power_t; // Power (Relay) type #define WEB_LOG_SIZE 4000 // Max number of characters in weblog #endif -#define MAX_BACKLOG 16 // Max number of commands in backlog (chk backlog_index and backlog_pointer code) +#define MAX_BACKLOG 30 // Max number of commands in backlog #define MIN_BACKLOG_DELAY 2 // Minimal backlog delay in 0.1 seconds #define SOFT_BAUDRATE 9600 // Default software serial baudrate diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 6ef37513e..aff1fd224 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -463,16 +463,13 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) int command_code = GetCommandCode(command, sizeof(command), type, kTasmotaCommands); if (CMND_BACKLOG == command_code) { if (data_len) { + uint8_t bl_pointer = (!backlog_pointer) ? MAX_BACKLOG -1 : backlog_pointer; + bl_pointer--; char *blcommand = strtok(dataBuf, ";"); - while (blcommand != NULL) { + while ((blcommand != NULL) && (backlog_index != bl_pointer)) { backlog[backlog_index] = String(blcommand); backlog_index++; -/* - if (backlog_index >= MAX_BACKLOG) { - backlog_index = 0; - } -*/ - backlog_index &= 0xF; + if (backlog_index >= MAX_BACKLOG) backlog_index = 0; blcommand = strtok(NULL, ";"); } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_APPENDED); @@ -1756,12 +1753,7 @@ void StateLoop() ExecuteCommand((char*)backlog[backlog_pointer].c_str()); backlog_mutex = 0; backlog_pointer++; -/* - if (backlog_pointer >= MAX_BACKLOG) { - backlog_pointer = 0; - } -*/ - backlog_pointer &= 0xF; + if (backlog_pointer >= MAX_BACKLOG) backlog_pointer = 0; } } From ce98c6cacc448830b4eac4ab4f2f9e3eb738f2a3 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Sat, 31 Mar 2018 19:56:16 +0200 Subject: [PATCH 04/13] Add multiple colors to Led command 5.12.0i * Add multiple color entry support for command Led like Led2 120000.001200.000012 setting led2 as Red, Led3 as Green and Led4 as Blue (#2303) --- sonoff/_releasenotes.ino | 3 ++- sonoff/xdrv_01_light.ino | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index f87587c10..50b7a7ca0 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -4,9 +4,10 @@ * Add optional Timer configuration webpage to be enabled in user_config.h with define USE_TIMERS_WEB * Add Home Assistant MQTT Discovery for Buttons and change SetOption19 response (#2277) * Add support for SGP30 gas and air quality sensor (#2307) + * Add multiple color entry support for command Led like Led2 120000.001200.000012 setting led2 as Red, Led3 as Green and Led4 as Blue (#2303) * Change webpage parameter communication * Change Timer parameter Device to more obvious Output - * Change max number of commands in Backlog from 15 to 30 + * Change max number of commands in Backlog from 15 to 30 and ignore commands overflowing * Change MQTT response topic for Energy changes from ENERGY to SENSOR (#2229, #2251) * Change default Reset configuration time from 4 seconds to 40 seconds on Button hold (#2268) * diff --git a/sonoff/xdrv_01_light.ino b/sonoff/xdrv_01_light.ino index 54c7cebc9..9158442a9 100644 --- a/sonoff/xdrv_01_light.ino +++ b/sonoff/xdrv_01_light.ino @@ -1114,8 +1114,16 @@ boolean LightCommand() #ifdef USE_WS2812 // *********************************************************************** else if ((CMND_LED == command_code) && (LT_WS2812 == light_type) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= Settings.light_pixels)) { if (XdrvMailbox.data_len > 0) { - if (LightColorEntry(XdrvMailbox.data, XdrvMailbox.data_len)) { - Ws2812SetColor(XdrvMailbox.index, light_entry_color[0], light_entry_color[1], light_entry_color[2], light_entry_color[3]); + char *p; + uint16_t idx = XdrvMailbox.index; + for (char *color = strtok_r(XdrvMailbox.data, ".", &p); color; color = strtok_r(NULL, ".", &p)) { + if (LightColorEntry(color, strlen(color))) { + Ws2812SetColor(idx, light_entry_color[0], light_entry_color[1], light_entry_color[2], light_entry_color[3]); + idx++; + if (idx >= Settings.light_pixels) break; + } else { + break; + } } } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, Ws2812GetColor(XdrvMailbox.index, scolor)); From 8af94521162e5a2fd0de80d4e944738610746228 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Sun, 1 Apr 2018 11:04:00 +0200 Subject: [PATCH 05/13] Change led multiple color sep from dot to space 5.12.0i * Add multiple color entry support for command Led like Led2 120000 001200 000012 setting led2 as Red, Led3 as Green and Led4 as Blue (#2303) --- sonoff/_releasenotes.ino | 2 +- sonoff/xdrv_01_light.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 50b7a7ca0..1de743336 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -4,7 +4,7 @@ * Add optional Timer configuration webpage to be enabled in user_config.h with define USE_TIMERS_WEB * Add Home Assistant MQTT Discovery for Buttons and change SetOption19 response (#2277) * Add support for SGP30 gas and air quality sensor (#2307) - * Add multiple color entry support for command Led like Led2 120000.001200.000012 setting led2 as Red, Led3 as Green and Led4 as Blue (#2303) + * Add multiple color entry support for command Led like Led2 120000 001200 000012 setting led2 as Red, Led3 as Green and Led4 as Blue (#2303) * Change webpage parameter communication * Change Timer parameter Device to more obvious Output * Change max number of commands in Backlog from 15 to 30 and ignore commands overflowing diff --git a/sonoff/xdrv_01_light.ino b/sonoff/xdrv_01_light.ino index 9158442a9..2c9b04890 100644 --- a/sonoff/xdrv_01_light.ino +++ b/sonoff/xdrv_01_light.ino @@ -1116,7 +1116,7 @@ boolean LightCommand() if (XdrvMailbox.data_len > 0) { char *p; uint16_t idx = XdrvMailbox.index; - for (char *color = strtok_r(XdrvMailbox.data, ".", &p); color; color = strtok_r(NULL, ".", &p)) { + for (char *color = strtok_r(XdrvMailbox.data, " ", &p); color; color = strtok_r(NULL, " ", &p)) { if (LightColorEntry(color, strlen(color))) { Ws2812SetColor(idx, light_entry_color[0], light_entry_color[1], light_entry_color[2], light_entry_color[3]); idx++; From 1ccac05b43f71d72901b892218e7a3f5460d9825 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Sun, 1 Apr 2018 21:37:00 +0200 Subject: [PATCH 06/13] Add Domoticz Battery and RSSI Quality 5.12.0i * Add Domoticz Battery and RSSI Quality (#1604) --- sonoff/_releasenotes.ino | 1 + sonoff/xdrv_05_domoticz.ino | 40 ++++++++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 1de743336..2c5c80c70 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -2,6 +2,7 @@ * Add 16 timers using commands Timer and Timers (#1091) * Add commands Timer 0 to clear timer and Timer 1..16 to copy timer * Add optional Timer configuration webpage to be enabled in user_config.h with define USE_TIMERS_WEB + * Add Domoticz Battery and RSSI Quality (#1604) * Add Home Assistant MQTT Discovery for Buttons and change SetOption19 response (#2277) * Add support for SGP30 gas and air quality sensor (#2307) * Add multiple color entry support for command Led like Led2 120000 001200 000012 setting led2 as Red, Led3 as Green and Led4 as Blue (#2303) diff --git a/sonoff/xdrv_05_domoticz.ino b/sonoff/xdrv_05_domoticz.ino index 5aa6a7c43..ea2b39319 100644 --- a/sonoff/xdrv_05_domoticz.ino +++ b/sonoff/xdrv_05_domoticz.ino @@ -35,6 +35,8 @@ const char HTTP_FORM_DOMOTICZ_TIMER[] PROGMEM = "" D_DOMOTICZ_UPDATE_TIMER " (" STR(DOMOTICZ_UPDATE_TIMER) ")"; #endif // USE_WEBSERVER +const char DOMOTICZ_MESSAGE[] PROGMEM = "{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"%s\",\"Battery\":%d,\"RSSI\":%d}"; + enum DomoticzCommands { CMND_IDX, CMND_KEYIDX, CMND_SWITCHIDX, CMND_SENSORIDX, CMND_UPDATETIMER }; const char kDomoticzCommands[] PROGMEM = D_CMND_IDX "|" D_CMND_KEYIDX "|" D_CMND_SWITCHIDX "|" D_CMND_SENSORIDX "|" D_CMND_UPDATETIMER ; @@ -57,6 +59,32 @@ boolean domoticz_subscribe = false; int domoticz_update_timer = 0; byte domoticz_update_flag = 1; +int DomoticzBatteryQuality() +{ + // Battery 0%: ESP 2.6V (minimum operating voltage is 2.5) + // Battery 100%: ESP 3.6V (maximum operating voltage is 3.6) + // Battery 101% to 200%: ESP over 3.6V (means over maximum operating voltage) + + int quality = 0; // Voltage range from 2,6V > 0% to 3,6V > 100% + + uint16_t voltage = ESP.getVcc(); + if (voltage <= 2600) { + quality = 0; + } else if (voltage >= 4600) { + quality = 200; + } else { + quality = (voltage - 2600) / 10; + } + return quality; +} + +int DomoticzRssiQuality() +{ + // RSSI range: 0% to 10% (12 means disable RSSI in Domoticz) + + return WifiGetRssiAsQuality(WiFi.RSSI()) / 10; +} + void MqttPublishDomoticzPowerState(byte device) { char sdimmer[8]; @@ -66,8 +94,8 @@ void MqttPublishDomoticzPowerState(byte device) } if (Settings.flag.mqtt_enabled && Settings.domoticz_relay_idx[device -1]) { snprintf_P(sdimmer, sizeof(sdimmer), PSTR("%d"), Settings.light_dimmer); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"%s\"}"), - Settings.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0, (light_type) ? sdimmer : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), DOMOTICZ_MESSAGE, + Settings.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0, (light_type) ? sdimmer : "", DomoticzBatteryQuality(), DomoticzRssiQuality()); MqttPublish(domoticz_in_topic); } } @@ -275,13 +303,15 @@ uint8_t DomoticzHumidityState(char *hum) void DomoticzSensor(byte idx, char *data) { if (Settings.domoticz_sensor_idx[idx]) { - char dmess[64]; + char dmess[90]; memcpy(dmess, mqtt_data, sizeof(dmess)); if (DZ_AIRQUALITY == idx) { - snprintf_P(mqtt_data, sizeof(dmess), PSTR("{\"idx\":%d,\"nvalue\":%s}"), Settings.domoticz_sensor_idx[idx], data); + snprintf_P(mqtt_data, sizeof(dmess), PSTR("{\"idx\":%d,\"nvalue\":%s,\"Battery\":%d,\"RSSI\":%d}"), + Settings.domoticz_sensor_idx[idx], data, DomoticzBatteryQuality(), DomoticzRssiQuality()); } else { - snprintf_P(mqtt_data, sizeof(dmess), PSTR("{\"idx\":%d,\"nvalue\":0,\"svalue\":\"%s\"}"), Settings.domoticz_sensor_idx[idx], data); + snprintf_P(mqtt_data, sizeof(dmess), DOMOTICZ_MESSAGE, + Settings.domoticz_sensor_idx[idx], 0, data, DomoticzBatteryQuality(), DomoticzRssiQuality()); } MqttPublish(domoticz_in_topic); memcpy(mqtt_data, dmess, sizeof(dmess)); From fa556897fe1711fb1d2dae6eea91a9a4a25dd571 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Sun, 1 Apr 2018 21:54:15 +0200 Subject: [PATCH 07/13] Change SGP30 CO2 into eCO2 Change SGP30 CO2 into eCO2 (#2307) --- sonoff/i18n.h | 3 ++- sonoff/language/cs-CZ.h | 1 + sonoff/language/de-DE.h | 1 + sonoff/language/en-GB.h | 1 + sonoff/language/es-AR.h | 1 + sonoff/language/fr-FR.h | 1 + sonoff/language/hu-HU.h | 1 + sonoff/language/it-IT.h | 1 + sonoff/language/nl-NL.h | 1 + sonoff/language/pl-PL.h | 1 + sonoff/language/pt-PT.h | 1 + sonoff/language/ru-RU.h | 1 + sonoff/language/zh-CN.h | 1 + sonoff/language/zh-TW.h | 1 + sonoff/xsns_21_sgp30.ino | 11 ++++++----- 15 files changed, 21 insertions(+), 6 deletions(-) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index b026d0af5..95b17fea6 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -48,6 +48,7 @@ #define D_JSON_DATA "Data" #define D_JSON_DNSSERVER "DNSServer" #define D_JSON_DONE "Done" +#define D_JSON_ECO2 "eCO2" #define D_JSON_EMPTY "Empty" #define D_JSON_ENDDST "EndDST" // End Daylight Savings Time #define D_JSON_ERASE "Erase" @@ -481,7 +482,7 @@ const char HTTP_SNS_PRESSURE[] PROGMEM = "%s{s}%s " D_PRESSURE "{m}%s " D_UNIT_P const char HTTP_SNS_SEAPRESSURE[] PROGMEM = "%s{s}%s " D_PRESSUREATSEALEVEL "{m}%s " D_UNIT_PRESSURE "{e}"; // {s} = , {m} = , {e} = const char HTTP_SNS_ANALOG[] PROGMEM = "%s{s}%s " D_ANALOG_INPUT "%d{m}%d{e}"; // {s} = , {m} = , {e} = -#if defined(USE_MHZ19) || defined(USE_SENSEAIR) || defined(USE_SGP30) +#if defined(USE_MHZ19) || defined(USE_SENSEAIR) const char HTTP_SNS_CO2[] PROGMEM = "%s{s}%s " D_CO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"; // {s} = , {m} = , {e} = #endif // USE_WEBSERVER diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index 9f2740ecb..21336443c 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "Server DNS" #define D_DONE "Provedeno" #define D_DST_TIME "DST" +#define D_ECO2 "eCO2" #define D_EMULATION "Emulace" #define D_ENABLED "Otevřený" #define D_ERASE "Smaž" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 45040412e..caa74fd41 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "DNS Server" #define D_DONE "erledigt" #define D_DST_TIME "DST" +#define D_ECO2 "eCO2" #define D_EMULATION "Emulation" #define D_ENABLED "aktiviert" #define D_ERASE "löschen" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index dadd68f85..484946200 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "DNS Server" #define D_DONE "Done" #define D_DST_TIME "DST" +#define D_ECO2 "eCO2" #define D_EMULATION "Emulation" #define D_ENABLED "Enabled" #define D_ERASE "Erase" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index ae9acf887..143ee4d3c 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "DNS Server" #define D_DONE "Listo" #define D_DST_TIME "DST" +#define D_ECO2 "eCO2" #define D_EMULATION "Emulación" #define D_ENABLED "Habilitado" #define D_ERASE "Borrar" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index d5a62db80..5d09cfcb6 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "Serveur DNS" #define D_DONE "Fait" #define D_DST_TIME "DST" +#define D_ECO2 "eCO2" #define D_EMULATION "Emulation" #define D_ENABLED "Activé" #define D_ERASE "Effacer" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index f4dc7a0c9..e043b1b96 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "DNS Szerver" #define D_DONE "Kész" #define D_DST_TIME "DST" +#define D_ECO2 "eCO2" #define D_EMULATION "Emuláció" #define D_ENABLED "Engedélyezve" #define D_ERASE "Törlés" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index 8a3a80702..59851e677 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "DNS Server" #define D_DONE "Fatto" #define D_DST_TIME "DST" +#define D_ECO2 "eCO2" #define D_EMULATION "Emulazione" #define D_ENABLED "Abilitato" #define D_ERASE "Cancellare" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index 507213f07..b21bea2aa 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "DNS Server" #define D_DONE "Klaar" #define D_DST_TIME "ZT" +#define D_ECO2 "eCO2" #define D_EMULATION "Emulatie" #define D_ENABLED "Geactiveerd" #define D_ERASE "Wissen" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 856e682bf..9d0352315 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "Server DNS" #define D_DONE "Wykonane" #define D_DST_TIME "DST" +#define D_ECO2 "eCO2" #define D_EMULATION "Emulacja" #define D_ENABLED "Otwarty" #define D_ERASE "Nadpisz" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index 482e40474..5c52cd528 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "Servidor DNS" #define D_DONE "Concluído" #define D_DST_TIME "DST" +#define D_ECO2 "eCO2" #define D_EMULATION "Emulação" #define D_ENABLED "Habilitado" #define D_ERASE "Apagar" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index ee84a50b0..d11bfcda2 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "DNS Сервер" #define D_DONE "Выполнено" #define D_DST_TIME "DST" +#define D_ECO2 "eCO2" #define D_EMULATION "Эмуляция" #define D_ENABLED "Активно" #define D_ERASE "Стирать" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index a105a9c3a..f9d0d5cc2 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "DNS服务器" #define D_DONE "完成" #define D_DST_TIME "DST" +#define D_ECO2 "eCO2" #define D_EMULATION "设备模拟" #define D_ENABLED "启用" #define D_ERASE "擦除" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index 118e0d719..a95b772ca 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -77,6 +77,7 @@ #define D_DNS_SERVER "DNS伺服器" #define D_DONE "完成" #define D_DST_TIME "DST" +#define D_ECO2 "eCO2" #define D_EMULATION "設備模擬" #define D_ENABLED "啟用" #define D_ERASE "刪除" diff --git a/sonoff/xsns_21_sgp30.ino b/sonoff/xsns_21_sgp30.ino index 205c34437..eed03ce7f 100644 --- a/sonoff/xsns_21_sgp30.ino +++ b/sonoff/xsns_21_sgp30.ino @@ -64,20 +64,21 @@ void Sgp30Update() // Perform every second to ensure proper operation of the ba } } -const char HTTP_SNS_TVOC[] PROGMEM = "%s{s}SGP30 " D_TVOC "{m}%d " D_UNIT_PARTS_PER_BILLION "{e}"; +const char HTTP_SNS_SGP30[] PROGMEM = "%s" + "{s}SGP30 " D_ECO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}" // {s} = , {m} = , {e} = + "{s}SGP30 " D_TVOC "{m}%d " D_UNIT_PARTS_PER_BILLION "{e}"; void Sgp30Show(boolean json) { if (sgp30_ready) { if (json) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SGP30\":{\"" D_JSON_CO2 "\":%d,\"" D_JSON_TVOC "\":%d}"), mqtt_data, sgp.eCO2, sgp.TVOC); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SGP30\":{\"" D_JSON_ECO2 "\":%d,\"" D_JSON_TVOC "\":%d}"), mqtt_data, sgp.eCO2, sgp.TVOC); #ifdef USE_DOMOTICZ - DomoticzSensor(DZ_AIRQUALITY, sgp.eCO2); + DomoticzSensor(DZ_AIRQUALITY, sgp.eCO2); #endif // USE_DOMOTICZ } else { #ifdef USE_WEBSERVER - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_CO2, mqtt_data, "SGP30", sgp.eCO2); - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TVOC, mqtt_data, sgp.TVOC); + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SGP30, mqtt_data, sgp.eCO2, sgp.TVOC); #endif } } From 8ddd121953a2c4bdcab5f5473ffad6b05da35ec3 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Mon, 2 Apr 2018 11:24:36 +0200 Subject: [PATCH 08/13] Change user_config_override usage 5.12.0i * Change user_config_override usage by providing user_config_override_sample.h (#2228) --- README.md | 20 +++--- platformio.ini | 57 +++++++++++++---- sonoff/sonoff.ino | 4 +- sonoff/user_config.h | 3 + sonoff/user_config_override.h | 44 ------------- sonoff/user_config_override_sample.h | 93 ++++++++++++++++++++++++++++ 6 files changed, 149 insertions(+), 72 deletions(-) delete mode 100644 sonoff/user_config_override.h create mode 100644 sonoff/user_config_override_sample.h diff --git a/README.md b/README.md index e4a1e3fb6..3300c8b0d 100644 --- a/README.md +++ b/README.md @@ -3,23 +3,17 @@ Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and Electr Current version is **5.12.0i** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. -### ATTENTION All versions +### Quick install -Only Flash Mode DOUT is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device. +Download one of the release binaries from https://github.com/arendst/Sonoff-Tasmota/releases and flash it to your hardware as documented in the wiki. -See [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Theo's-Tasmota-Tips) for background information. +### User compilation parameters -### ATTENTION Version 5 and up +If you want to compile Tasmota yourself keep in mind the following: -These versions use a new linker script to free flash memory for future code additions. It moves the settings from Spiffs to Eeprom. If you compile your own firmware download the new linker to your IDE or Platformio base folder. See [Wiki > Prerequisite](https://github.com/arendst/Sonoff-Tasmota/wiki/Prerequisite). - -Best practice to implement is: -- Open the webpage to your device -- Perform option ``Backup Configuration`` -- Upgrade new firmware using ``Firmware upgrade`` -- If configuration conversion fails keep the webpage open and perform ``Restore Configuration`` - -You should now have a device with 32k more code memory to play with. +- Only Flash Mode **DOUT** is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device. See [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Theo's-Tasmota-Tips) for background information. +- Tasmota uses a linker script WITHOUT spiffs for optimal code space. If you compile your own firmware on Arduino IDE and ESP/Arduino library 2.3.0 then download the new linker to your IDE or Platformio base folder. Later version of ESP/Arduino library already contain the correct linker script. See [Wiki > Prerequisite](https://github.com/arendst/Sonoff-Tasmota/wiki/Prerequisite). +- To make compile time changes to Tasmota can use the user_config_override.h file. It assures keeping your settings when you compile a new version. To use user_config.override.h copy the provided user_config.override_sample.h file to user_config.override.h and add your setting overrides. To enable the override file you will need to add a compile define as documented in the user_config_override_sample.h file ### Version Information diff --git a/platformio.ini b/platformio.ini index 675d7c891..87991ad88 100644 --- a/platformio.ini +++ b/platformio.ini @@ -14,6 +14,7 @@ src_dir = sonoff ;env_default = sonoff ;env_default = sonoff-minimal ;env_default = sonoff-xxl +;env_default = sonoff-CZ ;env_default = sonoff-DE ;env_default = sonoff-ES ;env_default = sonoff-FR @@ -24,6 +25,7 @@ src_dir = sonoff ;env_default = sonoff-PT ;env_default = sonoff-RU ;env_default = sonoff-CN +;env_default = sonoff-TW [env:sonoff] ;platform = espressif8266@1.5.0 ; v2.3.0 @@ -33,7 +35,7 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DUSE_CONFIG_OVERRIDE extra_scripts = pio/strip-floats.py ; *** Serial Monitor options @@ -60,7 +62,8 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -DBE_MINIMAL -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DBE_MINIMAL -DUSE_CONFIG_OVERRIDE + extra_scripts = pio/strip-floats.py ; Serial Monitor options @@ -74,12 +77,26 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -DUSE_ALL_SENSORS -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DUSE_ALL_SENSORS -DUSE_CONFIG_OVERRIDE extra_scripts = pio/strip-floats.py ; Serial Monitor options monitor_baud = 115200 +[env:sonoff-CZ] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 +platform = espressif8266 +framework = arduino +board = esp01_1m +board_flash_mode = dout +build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=cs-CZ +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=cs-CZ -DUSE_CONFIG_OVERRIDE +extra_scripts = pio/strip-floats.py + +; *** Serial Monitor options +monitor_baud = 115200 + [env:sonoff-DE] ;platform = espressif8266@1.5.0 ; v2.3.0 ;platform = espressif8266@1.6.0 ; v2.4.0 @@ -88,7 +105,7 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=de-DE -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=de-DE -DUSE_CONFIG_OVERRIDE extra_scripts = pio/strip-floats.py ; *** Serial Monitor options @@ -102,7 +119,7 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=es-AR -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=es-AR -DUSE_CONFIG_OVERRIDE extra_scripts = pio/strip-floats.py ; *** Serial Monitor options @@ -116,7 +133,7 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=fr-FR -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=fr-FR -DUSE_CONFIG_OVERRIDE extra_scripts = pio/strip-floats.py ; *** Serial Monitor options @@ -130,7 +147,7 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=hu-HU -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=hu-HU -DUSE_CONFIG_OVERRIDE extra_scripts = pio/strip-floats.py ; *** Serial Monitor options @@ -144,7 +161,7 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=it-IT -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=it-IT -DUSE_CONFIG_OVERRIDE extra_scripts = pio/strip-floats.py ; *** Serial Monitor options @@ -158,7 +175,7 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=nl-NL -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=nl-NL -DUSE_CONFIG_OVERRIDE extra_scripts = pio/strip-floats.py ; *** Serial Monitor options @@ -172,7 +189,7 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=pl-PL -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=pl-PL -DUSE_CONFIG_OVERRIDE extra_scripts = pio/strip-floats.py ; *** Serial Monitor options @@ -186,7 +203,7 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=pt-PT -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=pt-PT -DUSE_CONFIG_OVERRIDE extra_scripts = pio/strip-floats.py ; *** Serial Monitor options @@ -200,7 +217,7 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=ru-RU -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=ru-RU -DUSE_CONFIG_OVERRIDE extra_scripts = pio/strip-floats.py ; *** Serial Monitor options @@ -214,7 +231,21 @@ framework = arduino board = esp01_1m board_flash_mode = dout build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=zh-CN -lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=zh-CN -DUSE_CONFIG_OVERRIDE +extra_scripts = pio/strip-floats.py + +; *** Serial Monitor options +monitor_baud = 115200 + +[env:sonoff-TW] +;platform = espressif8266@1.5.0 ; v2.3.0 +;platform = espressif8266@1.6.0 ; v2.4.0 +platform = espressif8266 +framework = arduino +board = esp01_1m +board_flash_mode = dout +build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=zh-TW +;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DMY_LANGUAGE=zh-TW -DUSE_CONFIG_OVERRIDE extra_scripts = pio/strip-floats.py ; *** Serial Monitor options diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index aff1fd224..ba91347ed 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -32,9 +32,9 @@ #include "sonoff.h" // Enumeration used in user_config.h #include "user_config.h" // Fixed user configurable options -//#ifdef USE_CONFIG_OVERRIDE +#ifdef USE_CONFIG_OVERRIDE #include "user_config_override.h" // Configuration overrides for user_config.h -//#endif +#endif #include "i18n.h" // Language support configured by user_config.h #include "sonoff_template.h" // Hardware configuration diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 5b274624a..db5e9a50d 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -48,6 +48,9 @@ // As an IDE restriction it needs to be the same as the main .ino file #define CFG_HOLDER 0x20161209 // [Reset 1] Change this value to load following default configuration parameters + +//#define USE_CONFIG_OVERRIDE // Uncomment to use your own user_config_override.h file. See README.md + #define SAVE_DATA 1 // [SaveData] Save changed parameters to Flash (0 = disable, 1 - 3600 seconds) #define SAVE_STATE 1 // [SetOption0] Save changed power state to Flash (0 = disable, 1 = enable) diff --git a/sonoff/user_config_override.h b/sonoff/user_config_override.h deleted file mode 100644 index 1008faf72..000000000 --- a/sonoff/user_config_override.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - user_config_override.h - user configuration overrides user_config.h for Sonoff-Tasmota - - Copyright (C) 2018 Theo Arends - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef _USER_CONFIG_OVERRIDE_H_ -#define _USER_CONFIG_OVERRIDE_H_ - -/*****************************************************************************************************\ - * ATTENTION: - Changes to most PARAMETER defines will only override flash settings if you change - * define CFG_HOLDER. - * - Expect compiler warnings when no ifdef/undef/endif sequence is used. - * - You still need to update user_config.h for major defines MODULE and USE_MQTT_TLS. - * - Changing MODULE defines are not being tested for validity as they are in user_config.h. - * - Most parameters can be changed online using commands via MQTT, WebConsole or serial. - * - So I see no use in this but anyway, your on your own. -\*****************************************************************************************************/ - -// Examples -//#ifdef CFG_HOLDER -//#undef CFG_HOLDER -//#endif -//#define CFG_HOLDER 0x20161210 - -//#ifdef STA_SSID1 -//#undef STA_SSID1 -//#endif -//#define STA_SSID1 "yourssid1" - -#endif // _USER_CONFIG_OVERRIDE_H_ \ No newline at end of file diff --git a/sonoff/user_config_override_sample.h b/sonoff/user_config_override_sample.h new file mode 100644 index 000000000..81e209c5d --- /dev/null +++ b/sonoff/user_config_override_sample.h @@ -0,0 +1,93 @@ +/* + user_config_override.h - user configuration overrides user_config.h for Sonoff-Tasmota + + Copyright (C) 2018 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _USER_CONFIG_OVERRIDE_H_ +#define _USER_CONFIG_OVERRIDE_H_ + +// force the compiler to show a warning to confirm that this file is inlcuded +#warning **** Using Settings from user_config_override.h File *** + +/*****************************************************************************************************\ + * USAGE: + * To modify the stock configuration without changing the user_config.h file: + * (1) copy this file to "user_config_override.h" (It will be ignored by Git) + * (2) define your own settings below + * (3) for platformio: + * define USE_CONFIG_OVERRIDE as a build flags. + * ie1 : export PLATFORMIO_BUILD_FLAGS='-DUSE_CONFIG_OVERRIDE' + * ie2 : enable in file platformio.ini ;build_flags = -Wl,-Tesp8266.flash.1m0.ld -DUSE_CONFIG_OVERRIDE + * for Arduino IDE: + * enable define USE_CONFIG_OVERRIDE in user_config.h + ****************************************************************************************************** + * ATTENTION: + * - Changes to most PARAMETER defines will only override flash settings if you change define CFG_HOLDER. + * - Expect compiler warnings when no ifdef/undef/endif sequence is used. + * - You still need to update user_config.h for major defines MODULE and USE_MQTT_TLS. + * - Changing MODULE defines are not being tested for validity as they are in user_config.h. + * - Most parameters can be changed online using commands via MQTT, WebConsole or serial. +\*****************************************************************************************************/ + +/* +Examples : + +// Setup your own Wifi settings ------------------------------------------------------- +#undef STA_SSID1 +#define STA_SSID1 "YourSSID" // [Ssid1] Wifi SSID + +#undef STA_PASS1 +#define STA_PASS1 "YourWifiPassword" // [Password1] Wifi password + +// Setup your own MQTT settings ------------------------------------------------------- +#undef MQTT_HOST +#define MQTT_HOST "your-mqtt-server.com" // [MqttHost] + +#undef MQTT_PORT +#define MQTT_PORT 1883 // [MqttPort] MQTT port (10123 on CloudMQTT) + +#undef MQTT_USER +#define MQTT_USER "YourMqttUser" // [MqttUser] Optional user + +#undef MQTT_PASS +#define MQTT_PASS "YourMqttPass" // [MqttPassword] Optional password + +// You might even pass some parameters from the command line ---------------------------- +// Ie: export PLATFORMIO_BUILD_FLAGS='-DUSE_CONFIG_OVER -DMY_IP="192.168.1.99" -DMY_GW="192.168.1.1" -DMY_DNS="192.168.1.1"' + +#ifdef MY_IP +#undef WIFI_IP_ADDRESS +#define WIFI_IP_ADDRESS MY_IP // Set to 0.0.0.0 for using DHCP or IP address +#endif + +#ifdef MY_GW +#undef WIFI_GATEWAY +#define WIFI_GATEWAY MY_GW // if not using DHCP set Gateway IP address +#endif + +#ifdef MY_DNS +#undef WIFI_DNS +#define WIFI_DNS MY_DNS // If not using DHCP set DNS IP address (might be equal to WIFI_GATEWAY) +#endif + +*/ + + + + + +#endif // _USER_CONFIG_OVERRIDE_H_ \ No newline at end of file From 83294be8fec305744c223a822d6463be112cd524 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Mon, 2 Apr 2018 11:31:05 +0200 Subject: [PATCH 09/13] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3300c8b0d..84a7814f0 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,15 @@ Current version is **5.12.0i** - See [sonoff/_releasenotes.ino](https://github.c ### Quick install -Download one of the release binaries from https://github.com/arendst/Sonoff-Tasmota/releases and flash it to your hardware as documented in the wiki. +Download one of the released binaries from https://github.com/arendst/Sonoff-Tasmota/releases and flash it to your hardware as documented in the wiki. -### User compilation parameters +### Important User Compilation Information -If you want to compile Tasmota yourself keep in mind the following: +If you want to compile Sonoff-Tasmota yourself keep in mind the following: - Only Flash Mode **DOUT** is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device. See [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Theo's-Tasmota-Tips) for background information. -- Tasmota uses a linker script WITHOUT spiffs for optimal code space. If you compile your own firmware on Arduino IDE and ESP/Arduino library 2.3.0 then download the new linker to your IDE or Platformio base folder. Later version of ESP/Arduino library already contain the correct linker script. See [Wiki > Prerequisite](https://github.com/arendst/Sonoff-Tasmota/wiki/Prerequisite). -- To make compile time changes to Tasmota can use the user_config_override.h file. It assures keeping your settings when you compile a new version. To use user_config.override.h copy the provided user_config.override_sample.h file to user_config.override.h and add your setting overrides. To enable the override file you will need to add a compile define as documented in the user_config_override_sample.h file +- Sonoff-Tasmota uses a linker script WITHOUT spiffs for optimal code space. If you compile using ESP/Arduino library 2.3.0 then download the new linker to your Arduino IDE or Platformio base folder. Later version of ESP/Arduino library already contain the correct linker script. See [Wiki > Prerequisite](https://github.com/arendst/Sonoff-Tasmota/wiki/Prerequisite). +- To make compile time changes to Sonoff-Tasmota it can use the ``user_config_override.h`` file. It assures keeping your settings when you compile a new version. To use ``user_config.override.h`` copy the provided ``user_config.override_sample.h`` file and add your setting overrides. To enable the override file you will need to add a compile define as documented in the ``user_config_override_sample.h`` file. ### Version Information From f3c553f3da41cd481187665db88352bc85a7c085 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Mon, 2 Apr 2018 11:34:49 +0200 Subject: [PATCH 10/13] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 84a7814f0..7734cacfd 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ Download one of the released binaries from https://github.com/arendst/Sonoff-Tas If you want to compile Sonoff-Tasmota yourself keep in mind the following: - Only Flash Mode **DOUT** is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device. See [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Theo's-Tasmota-Tips) for background information. -- Sonoff-Tasmota uses a linker script WITHOUT spiffs for optimal code space. If you compile using ESP/Arduino library 2.3.0 then download the new linker to your Arduino IDE or Platformio base folder. Later version of ESP/Arduino library already contain the correct linker script. See [Wiki > Prerequisite](https://github.com/arendst/Sonoff-Tasmota/wiki/Prerequisite). -- To make compile time changes to Sonoff-Tasmota it can use the ``user_config_override.h`` file. It assures keeping your settings when you compile a new version. To use ``user_config.override.h`` copy the provided ``user_config.override_sample.h`` file and add your setting overrides. To enable the override file you will need to add a compile define as documented in the ``user_config_override_sample.h`` file. +- Sonoff-Tasmota uses a 1M linker script WITHOUT spiffs for optimal code space. If you compile using ESP/Arduino library 2.3.0 then download the provided new linker script to your Arduino IDE or Platformio base folder. Later version of ESP/Arduino library already contain the correct linker script. See [Wiki > Prerequisite](https://github.com/arendst/Sonoff-Tasmota/wiki/Prerequisite). +- To make compile time changes to Sonoff-Tasmota it can use the ``user_config_override.h`` file. It assures keeping your settings when you download and compile a new version. To use ``user_config.override.h`` you will have to make a copy of the provided ``user_config.override_sample.h`` file and add your setting overrides. To enable the override file you will need to use a compile define as documented in the ``user_config_override_sample.h`` file. ### Version Information From 883fa4ce8d18c0bafead084bc93a5f898ea401be Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Mon, 2 Apr 2018 14:19:57 +0200 Subject: [PATCH 11/13] Add hexadecimal Data entry to command IrSend 5.12.0i * Add hexadecimal Data entry to command IrSend using 0x notation (#1290, #2314) --- sonoff/_releasenotes.ino | 2 ++ sonoff/xdrv_02_irremote.ino | 19 +++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 2c5c80c70..d5fed07f2 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -2,6 +2,7 @@ * Add 16 timers using commands Timer and Timers (#1091) * Add commands Timer 0 to clear timer and Timer 1..16 to copy timer * Add optional Timer configuration webpage to be enabled in user_config.h with define USE_TIMERS_WEB + * Add hexadecimal Data entry to command IrSend using 0x notation (#1290, #2314) * Add Domoticz Battery and RSSI Quality (#1604) * Add Home Assistant MQTT Discovery for Buttons and change SetOption19 response (#2277) * Add support for SGP30 gas and air quality sensor (#2307) @@ -9,6 +10,7 @@ * Change webpage parameter communication * Change Timer parameter Device to more obvious Output * Change max number of commands in Backlog from 15 to 30 and ignore commands overflowing + * Change user_config_override usage by providing user_config_override_sample.h (#2228) * Change MQTT response topic for Energy changes from ENERGY to SENSOR (#2229, #2251) * Change default Reset configuration time from 4 seconds to 40 seconds on Button hold (#2268) * diff --git a/sonoff/xdrv_02_irremote.ino b/sonoff/xdrv_02_irremote.ino index 94f57baae..896faa37a 100644 --- a/sonoff/xdrv_02_irremote.ino +++ b/sonoff/xdrv_02_irremote.ino @@ -284,26 +284,25 @@ boolean IrSendCommand() uint32_t bits = 0; uint32_t data = 0; - for (uint16_t i = 0; i <= sizeof(dataBufUc); i++) { - dataBufUc[i] = toupper(XdrvMailbox.data[i]); - } + UpperCase(dataBufUc, XdrvMailbox.data); if (!strcasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_IRSEND))) { if (XdrvMailbox.data_len) { StaticJsonBuffer<128> jsonBuf; - JsonObject &ir_json = jsonBuf.parseObject(dataBufUc); - if (!ir_json.success()) { + JsonObject &root = jsonBuf.parseObject(dataBufUc); + if (!root.success()) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_IRSEND "\":\"" D_JSON_INVALID_JSON "\"}")); // JSON decode failed } else { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_IRSEND "\":\"" D_JSON_DONE "\"}")); - protocol = ir_json[D_JSON_IR_PROTOCOL]; - bits = ir_json[D_JSON_IR_BITS]; - data = ir_json[D_JSON_IR_DATA]; + char parm_uc[10]; + protocol = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_PROTOCOL))]; + bits = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_BITS))]; + data = strtoul(root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_DATA))], NULL, 0); if (protocol && bits && data) { int protocol_code = GetCommandCode(protocol_text, sizeof(protocol_text), protocol, kIrRemoteProtocols); - snprintf_P(log_data, sizeof(log_data), PSTR("IRS: protocol_text %s, protocol %s, bits %d, data %d, protocol_code %d"), - protocol_text, protocol, bits, data, protocol_code); + snprintf_P(log_data, sizeof(log_data), PSTR("IRS: protocol_text %s, protocol %s, bits %d, data %u (0x%lX), protocol_code %d"), + protocol_text, protocol, bits, data, data, protocol_code); AddLog(LOG_LEVEL_DEBUG); switch (protocol_code) { From dd5956020021aac5d7285043c8a40adf5967c924 Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Mon, 2 Apr 2018 15:00:26 +0200 Subject: [PATCH 12/13] Add hexadecimal RGB color entry on RGBCW leds 5.12.0i * Add hexadecimal RGB color entry on RGBCW leds (#2304) --- sonoff/_releasenotes.ino | 1 + sonoff/xdrv_01_light.ino | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index d5fed07f2..6f2e91046 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -7,6 +7,7 @@ * Add Home Assistant MQTT Discovery for Buttons and change SetOption19 response (#2277) * Add support for SGP30 gas and air quality sensor (#2307) * Add multiple color entry support for command Led like Led2 120000 001200 000012 setting led2 as Red, Led3 as Green and Led4 as Blue (#2303) + * Add hexadecimal RGB color entry on RGBCW leds (#2304) * Change webpage parameter communication * Change Timer parameter Device to more obvious Output * Change max number of commands in Backlog from 15 to 30 and ignore commands overflowing diff --git a/sonoff/xdrv_01_light.ino b/sonoff/xdrv_01_light.ino index 2c9b04890..9230c1529 100644 --- a/sonoff/xdrv_01_light.ino +++ b/sonoff/xdrv_01_light.ino @@ -991,11 +991,10 @@ boolean LightColorEntry(char *buffer, uint8_t buffer_length) light_entry_color[i++] = atoi(str); } } -// entry_type = (light_subtype == i) ? 2 : 0; // Decimal entry_type = 2; // Decimal } - else if ((2 * light_subtype) == buffer_length) { // Hexadecimal entry - for (byte i = 0; i < light_subtype; i++) { + else if (((2 * light_subtype) == buffer_length) || (buffer_length > 3)) { // Hexadecimal entry + for (byte i = 0; i < buffer_length / 2; i++) { strlcpy(scolor, buffer + (i *2), 3); light_entry_color[i] = (uint8_t)strtol(scolor, &p, 16); } From f205a68d43f2b8c134c93ed09cd0f8d22305782f Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Tue, 3 Apr 2018 16:45:33 +0200 Subject: [PATCH 13/13] Add GPIO13 to Sonoff Dev (#2341) --- sonoff/sonoff_template.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 2fba23102..d8498d687 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -487,7 +487,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_USER, // GPIO05 Optional sensor 0, 0, 0, 0, 0, 0, // Flash connection GPIO_USER, // GPIO12 - GPIO_LED1_INV, // GPIO13 BLUE LED + GPIO_USER, // GPIO13 BLUE LED GPIO_USER, // GPIO14 Optional sensor 0, // GPIO15 0, // GPIO16