Merge branch 'arendst/development' into development

This commit is contained in:
reloxx13 2018-04-03 19:16:07 +02:00
commit 7f691e9fad
40 changed files with 970 additions and 168 deletions

View File

@ -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 released 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.
### Important User Compilation Information
### ATTENTION Version 5 and up
If you want to compile Sonoff-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.
- 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

View File

@ -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**

View File

@ -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.

View File

@ -0,0 +1,4 @@
*~
Doxyfile*
doxygen_sqlite3.db
html

View File

@ -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)

View File

@ -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; i<commandLength; i++) {
_i2c->write(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; i<replylen; i++) {
replybuffer[i] = _i2c->read();
#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<readlen; i++) {
uint8_t crc = generateCRC(replybuffer+i*3, 2);
#ifdef I2C_DEBUG
Serial.print("\t\tCRC calced: 0x"); Serial.print(crc, HEX);
Serial.print(" vs. 0x"); Serial.println(replybuffer[i * 3 + 2], HEX);
#endif
if (crc != replybuffer[i * 3 + 2])
return false;
// success! store it
readdata[i] = replybuffer[i*3];
readdata[i] <<= 8;
readdata[i] |= replybuffer[i*3 + 1];
#ifdef I2C_DEBUG
Serial.print("\t\tRead: 0x"); Serial.println(readdata[i], HEX);
#endif
}
return true;
}
uint8_t Adafruit_SGP30::generateCRC(uint8_t *data, uint8_t datalen) {
// calculates 8-Bit checksum with given polynomial
uint8_t crc = SGP30_CRC8_INIT;
for (uint8_t i=0; i<datalen; i++) {
crc ^= data[i];
for (uint8_t b=0; b<8; b++) {
if (crc & 0x80)
crc = (crc << 1) ^ SGP30_CRC8_POLYNOMIAL;
else
crc <<= 1;
}
}
return crc;
}

View File

@ -0,0 +1,68 @@
/*!
* @file Adafruit_SGP30.h
*
* 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!
*
* Written by Ladyada for Adafruit Industries.
*
* BSD license, all text here must be included in any redistribution.
*
*/
#include "Arduino.h"
#include <Wire.h>
// 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);
};

View File

@ -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

View File

@ -0,0 +1,45 @@
#include <Wire.h>
#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);
}
}

View File

@ -0,0 +1,9 @@
name=Adafruit SGP30 Sensor
version=1.0.2
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
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=*

View File

@ -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.

View File

@ -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

View File

@ -2,11 +2,18 @@
* 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 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)
* 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 default Reset configuration time from 4 seconds to 40 seconds on Button hold (#2268)
* 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)
*
* 5.12.0h
* Add optional Arduino OTA support to be enabled in user_config.h (#1998)

View File

@ -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"
@ -111,6 +112,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"
@ -357,6 +359,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"
/********************************************************************************************/
@ -381,6 +384,8 @@ enum UnitNames {
UNIT_MILLIAMPERE,
UNIT_MILLISECOND,
UNIT_MINUTE,
UNIT_PPB,
UNIT_PPD,
UNIT_PPM,
UNIT_PERCENTAGE,
UNIT_PRESSURE,
@ -399,6 +404,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 "|"

View File

@ -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ž"
@ -142,6 +143,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 +439,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"

View File

@ -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"
@ -142,6 +143,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 +439,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"

View File

@ -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"
@ -142,6 +143,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 +439,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"

View File

@ -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"
@ -142,6 +143,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 +439,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"

View File

@ -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"
@ -142,6 +143,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 +439,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"

View File

@ -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"
@ -142,6 +143,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 +439,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"

View File

@ -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"
@ -142,6 +143,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 +439,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"

View File

@ -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"
@ -142,6 +143,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 +439,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"

View File

@ -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"
@ -142,6 +143,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 +439,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"

View File

@ -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"
@ -142,6 +143,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 +439,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"

View File

@ -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 "Стирать"
@ -142,6 +143,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 +439,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 "гПа"

View File

@ -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 "擦除"
@ -142,6 +143,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 +439,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 "百帕"

View File

@ -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 "刪除"
@ -142,6 +143,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 +439,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 "百帕"

View File

@ -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

View File

@ -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
@ -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;
}
}

View File

@ -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 (+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)
@ -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

View File

@ -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

View File

@ -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)
@ -206,6 +209,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)

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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_

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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_

View File

@ -181,15 +181,17 @@ const char HTTP_BTN_MENU1[] PROGMEM =
"<br/><form action='cs' method='get'><button>" D_CONSOLE "</button></form>";
const char HTTP_BTN_RSTRT[] PROGMEM =
"<br/><form action='rb' method='get' onsubmit='return confirm(\"" D_CONFIRM_RESTART "\");'><button>" D_RESTART "</button></form>";
const char HTTP_BTN_MENU2[] PROGMEM =
"<br/><form action='md' method='get'><button>" D_CONFIGURE_MODULE "</button></form>"
const char HTTP_BTN_MENU_MODULE[] PROGMEM =
"<br/><form action='md' method='get'><button>" D_CONFIGURE_MODULE "</button></form>";
#ifdef USE_TIMERS
#ifdef USE_TIMERS_WEB
"<br/><form action='tm' method='get'><button>" D_CONFIGURE_TIMER "</button></form>"
const char HTTP_BTN_MENU_TIMER[] PROGMEM =
"<br/><form action='tm' method='get'><button>" D_CONFIGURE_TIMER "</button></form>";
#endif // USE_TIMERS_WEB
#endif // USE_TIMERS
const char HTTP_BTN_MENU_WIFI[] PROGMEM =
"<br/><form action='w0' method='get'><button>" D_CONFIGURE_WIFI "</button></form>";
const char HTTP_BTN_MENU3[] PROGMEM =
const char HTTP_BTN_MENU_MQTT[] PROGMEM =
"<br/><form action='mq' method='get'><button>" D_CONFIGURE_MQTT "</button></form>"
#ifdef USE_DOMOTICZ
"<br/><form action='dm' method='get'><button>" D_CONFIGURE_DOMOTICZ "</button></form>"
@ -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);

View File

@ -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);
}
@ -1114,8 +1113,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));

View File

@ -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) {

View File

@ -35,6 +35,8 @@ const char HTTP_FORM_DOMOTICZ_TIMER[] PROGMEM =
"<tr><td style='width:260px'><b>" D_DOMOTICZ_UPDATE_TIMER "</b> (" STR(DOMOTICZ_UPDATE_TIMER) ")</td><td style='width:70px'><input id='ut' name='ut' placeholder='" STR(DOMOTICZ_UPDATE_TIMER) "' value='{6'</td></tr>";
#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));

View File

@ -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;
}
}
}

116
sonoff/xsns_21_sgp30.ino Normal file
View File

@ -0,0 +1,116 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
#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_SGP30[] PROGMEM = "%s"
"{s}SGP30 " D_ECO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
"{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_ECO2 "\":%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_SGP30, mqtt_data, sgp.eCO2, 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